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