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