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 bool spirvVersion14;
103
GraphicsResourcesvkt::SpirVAssembly::GraphicsResources104 GraphicsResources()
105 : inputFormat (VK_FORMAT_R32G32B32A32_SFLOAT)
106 , verifyIO (DE_NULL)
107 , verifyBinary (DE_NULL)
108 , spirvVersion (SPIRV_VERSION_1_0)
109 , spirvVersion14 (false)
110 {}
111 };
112
113 // Interface data type.
114 struct IFDataType
115 {
IFDataTypevkt::SpirVAssembly::IFDataType116 IFDataType (deUint32 numE, NumberType elementT)
117 : numElements (numE)
118 , elementType (elementT)
119 {
120 DE_ASSERT(numE > 0 && numE < 5);
121 DE_ASSERT(elementT != NUMBERTYPE_END32 && elementT != NUMBERTYPE_END16);
122 }
123
IFDataTypevkt::SpirVAssembly::IFDataType124 IFDataType (const IFDataType& that)
125 : numElements (that.numElements)
126 , elementType (that.elementType)
127 {}
128
129 deUint32 getElementNumBytes (void) const;
getNumBytesvkt::SpirVAssembly::IFDataType130 deUint32 getNumBytes (void) const { return numElements * getElementNumBytes(); }
131
132 vk::VkFormat getVkFormat (void) const;
133
134 tcu::TextureFormat getTextureFormat (void) const;
135
136 std::string str (void) const;
137
elementIs32bitvkt::SpirVAssembly::IFDataType138 bool elementIs32bit (void) const { return elementType < NUMBERTYPE_END32; }
elementIs64bitvkt::SpirVAssembly::IFDataType139 bool elementIs64bit (void) const { return elementType > NUMBERTYPE_END16; }
140
isVectorvkt::SpirVAssembly::IFDataType141 bool isVector (void) const { return numElements > 1; }
142
143 deUint32 numElements;
144 NumberType elementType;
145 };
146
147 typedef std::pair<IFDataType, BufferSp> Interface;
148
149 // Interface variables used by graphics-pipeline-based tests.
150 class GraphicsInterfaces
151 {
152 public:
GraphicsInterfaces()153 GraphicsInterfaces ()
154 : rndMode (static_cast<RoundingModeFlags>(0))
155 {}
156
GraphicsInterfaces(const GraphicsInterfaces & that)157 GraphicsInterfaces (const GraphicsInterfaces& that)
158 : inputs (that.inputs)
159 , outputs (that.outputs)
160 , rndMode (that.rndMode)
161 {}
162
setInputOutput(const Interface & input,const Interface & output)163 void setInputOutput (const Interface& input, const Interface& output)
164 {
165 inputs.clear();
166 outputs.clear();
167 inputs.push_back(input);
168 outputs.push_back(output);
169 }
170
getInputType(void) const171 const IFDataType& getInputType (void) const
172 {
173 DE_ASSERT(inputs.size() == 1);
174 return inputs.front().first;
175 }
176
getOutputType(void) const177 const IFDataType& getOutputType (void) const
178 {
179 DE_ASSERT(outputs.size() == 1);
180 return outputs.front().first;
181 }
182
getInputBuffer(void) const183 const BufferSp& getInputBuffer (void) const
184 {
185 DE_ASSERT(inputs.size() == 1);
186 return inputs.front().second;
187 }
188
getOutputBuffer(void) const189 const BufferSp& getOutputBuffer (void) const
190 {
191 DE_ASSERT(outputs.size() == 1);
192 return outputs.front().second;
193 }
194
empty(void) const195 bool empty (void) const
196 {
197 return inputs.size() == 0;
198 }
199
setRoundingMode(RoundingModeFlags flag)200 void setRoundingMode (RoundingModeFlags flag)
201 {
202 rndMode = flag;
203 }
getRoundingMode(void) const204 RoundingModeFlags getRoundingMode (void) const
205 {
206 return rndMode;
207 }
208 private:
209 // vector<Interface> acts as a null-able Interface here. Canonically we should use
210 // std::unique_ptr, but sadly we cannot leverage C++11 in dEQP. dEQP has its own
211 // de::UniquePtr, but still cumbersome to use in InstanceContext and do copies
212 // at various places.
213 // Public methods should make sure that there are less than two elements in both
214 // members and both members have the same number of elements.
215 std::vector<Interface> inputs;
216 std::vector<Interface> outputs;
217 RoundingModeFlags rndMode;
218
219 };
220
221 struct PushConstants
222 {
223 public:
PushConstantsvkt::SpirVAssembly::PushConstants224 PushConstants (void)
225 {}
226
PushConstantsvkt::SpirVAssembly::PushConstants227 PushConstants (const PushConstants& that)
228 : pcs (that.pcs)
229 {}
230
setPushConstantvkt::SpirVAssembly::PushConstants231 void setPushConstant (const BufferSp& pc)
232 {
233 pcs.clear();
234 pcs.push_back(pc);
235 }
236
emptyvkt::SpirVAssembly::PushConstants237 bool empty (void) const
238 {
239 return pcs.empty();
240 }
241
getBuffervkt::SpirVAssembly::PushConstants242 const BufferSp& getBuffer(void) const
243 {
244 DE_ASSERT(pcs.size() == 1);
245 return pcs[0];
246 }
247
248 private:
249 // Right now we only support one field in the push constant block.
250 std::vector<BufferSp> pcs;
251 };
252
253 // Returns the corresponding buffer usage flag bit for the given descriptor type.
254 VkBufferUsageFlagBits getMatchingBufferUsageFlagBit (VkDescriptorType dType);
255
256 // Context for a specific test instantiation. For example, an instantiation
257 // may test colors yellow/magenta/cyan/mauve in a tesselation shader
258 // with an entry point named 'main_to_the_main'
259 struct InstanceContext
260 {
261 // Map of modules to what entry_points we care to use from those modules.
262 ModuleMap moduleMap;
263 tcu::RGBA inputColors[4];
264 tcu::RGBA outputColors[4];
265 // Concrete SPIR-V code to test via boilerplate specialization.
266 std::map<std::string, std::string> testCodeFragments;
267 StageToSpecConstantMap specConstants;
268 bool hasTessellation;
269 vk::VkShaderStageFlagBits requiredStages;
270 std::vector<std::string> requiredDeviceExtensions;
271 VulkanFeatures requestedFeatures;
272 PushConstants pushConstants;
273 // Specifies the (one or more) stages that use a customized shader code.
274 VkShaderStageFlags customizedStages;
275 // Possible resources used by the graphics pipeline.
276 // If it is not empty, a single descriptor set (number 0) will be allocated
277 // to point to all resources specified. Binding numbers are allocated in
278 // accord with the resources' order in the vector; outputs are allocated
279 // after inputs.
280 GraphicsResources resources;
281 // Possible interface variables use by the graphics pipeline.
282 // If it is not empty, input/output variables will be set up for shader stages
283 // in the test. Both the input and output variable will take location #2 in the
284 // pipeline for all stages, except that the output variable in the fragment
285 // stage will take location #1.
286 GraphicsInterfaces interfaces;
287 qpTestResult failResult;
288 std::string failMessageTemplate; //!< ${reason} in the template will be replaced with a detailed failure message
289 bool renderFullSquare; // Forces to render whole render area, though with background color
290 bool splitRenderArea; // Split render into multiple submissions.
291
292 InstanceContext (const tcu::RGBA (&inputs)[4],
293 const tcu::RGBA (&outputs)[4],
294 const std::map<std::string, std::string>& testCodeFragments_,
295 const StageToSpecConstantMap& specConstants_,
296 const PushConstants& pushConsants_,
297 const GraphicsResources& resources_,
298 const GraphicsInterfaces& interfaces_,
299 const std::vector<std::string>& extensions_,
300 VulkanFeatures vulkanFeatures_,
301 VkShaderStageFlags customizedStages_);
302
303 InstanceContext (const InstanceContext& other);
304
305 std::string getSpecializedFailMessage (const std::string& failureReason);
306 };
307
308 enum ShaderTask
309 {
310 SHADER_TASK_NONE = 0,
311 SHADER_TASK_NORMAL,
312 SHADER_TASK_UNUSED_VAR,
313 SHADER_TASK_UNUSED_FUNC,
314 SHADER_TASK_LAST
315 };
316
317 enum ShaderTaskIndex
318 {
319 SHADER_TASK_INDEX_VERTEX = 0,
320 SHADER_TASK_INDEX_GEOMETRY = 1,
321 SHADER_TASK_INDEX_TESS_CONTROL = 2,
322 SHADER_TASK_INDEX_TESS_EVAL = 3,
323 SHADER_TASK_INDEX_FRAGMENT = 4,
324 SHADER_TASK_INDEX_LAST = 5
325 };
326
327 typedef ShaderTask ShaderTaskArray[SHADER_TASK_INDEX_LAST];
328
329 struct UnusedVariableContext
330 {
331 InstanceContext instanceContext;
332 ShaderTaskArray shaderTasks;
333 VariableLocation variableLocation;
334
UnusedVariableContextvkt::SpirVAssembly::UnusedVariableContext335 UnusedVariableContext(const InstanceContext& ctx, const ShaderTaskArray& tasks, const VariableLocation& location)
336 : instanceContext(ctx), shaderTasks(), variableLocation(location)
337 {
338 deMemcpy(shaderTasks, tasks, sizeof(tasks));
339 }
340 };
341
342 // A description of a shader to be used for a single stage of the graphics pipeline.
343 struct ShaderElement
344 {
345 // The module that contains this shader entrypoint.
346 std::string moduleName;
347
348 // The name of the entrypoint.
349 std::string entryName;
350
351 // Which shader stage this entry point represents.
352 vk::VkShaderStageFlagBits stage;
353
354 ShaderElement (const std::string& moduleName_, const std::string& entryPoint_, vk::VkShaderStageFlagBits shaderStage_);
355 };
356
357 template <typename T>
numberToString(T number)358 const std::string numberToString (T number)
359 {
360 std::stringstream ss;
361 ss << number;
362 return ss.str();
363 }
364
365 void getDefaultColors (tcu::RGBA (&colors)[4]);
366
367 void getHalfColorsFullAlpha (tcu::RGBA (&colors)[4]);
368
369 void getInvertedDefaultColors (tcu::RGBA (&colors)[4]);
370
371 // Creates fragments that specialize into a simple pass-through shader (of any kind).
372 std::map<std::string, std::string> passthruFragments (void);
373
374 // Creates a combined shader module based on VkShaderStageFlagBits defined in InstanceContext.
375 void createCombinedModule (vk::SourceCollections& dst, InstanceContext ctx);
376
377 // Creates shaders with unused variables based on the UnusedVariableContext.
378 void createUnusedVariableModules (vk::SourceCollections& dst, UnusedVariableContext ctx);
379
380 // This has two shaders of each stage. The first
381 // is a passthrough, the second inverts the color.
382 void createMultipleEntries (vk::SourceCollections& dst, InstanceContext);
383
384 // Turns a vector of ShaderElements into an instance-context by setting up the mapping of modules
385 // to their contained shaders and stages. The inputs and expected outputs are given by inputColors
386 // and outputColors
387 InstanceContext createInstanceContext (const std::vector<ShaderElement>& elements,
388 const tcu::RGBA (&inputColors)[4],
389 const tcu::RGBA (&outputColors)[4],
390 const std::map<std::string, std::string>& testCodeFragments,
391 const StageToSpecConstantMap& specConstants,
392 const PushConstants& pushConstants,
393 const GraphicsResources& resources,
394 const GraphicsInterfaces& interfaces,
395 const std::vector<std::string>& extensions,
396 VulkanFeatures vulkanFeatures,
397 VkShaderStageFlags customizedStages,
398 const qpTestResult failResult = QP_TEST_RESULT_FAIL,
399 const std::string& failMessageTemplate = std::string());
400
401 // Same as above but using a statically sized array.
402 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 ())403 inline InstanceContext createInstanceContext (const ShaderElement (&elements)[N],
404 const tcu::RGBA (&inputColors)[4],
405 const tcu::RGBA (&outputColors)[4],
406 const std::map<std::string, std::string>& testCodeFragments,
407 const StageToSpecConstantMap& specConstants,
408 const PushConstants& pushConstants,
409 const GraphicsResources& resources,
410 const GraphicsInterfaces& interfaces,
411 const std::vector<std::string>& extensions,
412 VulkanFeatures vulkanFeatures,
413 VkShaderStageFlags customizedStages,
414 const qpTestResult failResult = QP_TEST_RESULT_FAIL,
415 const std::string& failMessageTemplate = std::string())
416 {
417 std::vector<ShaderElement> elementsVector(elements, elements + N);
418 return createInstanceContext(elementsVector, inputColors, outputColors, testCodeFragments, specConstants, pushConstants,
419 resources, interfaces, extensions, vulkanFeatures, customizedStages, failResult, failMessageTemplate);
420 }
421
422 // The same as createInstanceContext above, without extensions, spec constants, and resources.
423 InstanceContext createInstanceContext (const std::vector<ShaderElement>& elements,
424 tcu::RGBA (&inputColors)[4],
425 const tcu::RGBA (&outputColors)[4],
426 const std::map<std::string, std::string>& testCodeFragments);
427
428 // Same as above, but using a statically sized array.
429 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)430 inline InstanceContext createInstanceContext (const ShaderElement (&elements)[N],
431 tcu::RGBA (&inputColors)[4],
432 const tcu::RGBA (&outputColors)[4],
433 const std::map<std::string, std::string>& testCodeFragments)
434 {
435 std::vector<ShaderElement> elementsVector(elements, elements + N);
436 return createInstanceContext(elementsVector, inputColors, outputColors, testCodeFragments);
437 }
438
439 // The same as createInstanceContext above, but with default colors.
440 InstanceContext createInstanceContext (const std::vector<ShaderElement>& elements,
441 const std::map<std::string, std::string>& testCodeFragments);
442
443 // Same as above, but using a statically sized array.
444 template<size_t N>
createInstanceContext(const ShaderElement (& elements)[N],const std::map<std::string,std::string> & testCodeFragments)445 inline InstanceContext createInstanceContext (const ShaderElement (&elements)[N],
446 const std::map<std::string, std::string>& testCodeFragments)
447 {
448 std::vector<ShaderElement> elementsVector(elements, elements + N);
449 return createInstanceContext(elementsVector, testCodeFragments);
450 }
451
452
453 // Create an unused variable context for the given combination.
454 UnusedVariableContext createUnusedVariableContext(const ShaderTaskArray& shaderTasks, const VariableLocation& location);
455
456 void addShaderCodeCustomVertex (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions);
457 void addShaderCodeCustomTessControl (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions);
458 void addShaderCodeCustomTessEval (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions);
459 void addShaderCodeCustomGeometry (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions);
460 void addShaderCodeCustomFragment (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions);
461
462 void createTestForStage (vk::VkShaderStageFlagBits stage,
463 const std::string& name,
464 const tcu::RGBA (&inputColors)[4],
465 const tcu::RGBA (&outputColors)[4],
466 const std::map<std::string, std::string>& testCodeFragments,
467 const SpecConstants& specConstants,
468 const PushConstants& pushConstants,
469 const GraphicsResources& resources,
470 const GraphicsInterfaces& interfaces,
471 const std::vector<std::string>& extensions,
472 VulkanFeatures vulkanFeatures,
473 tcu::TestCaseGroup* tests,
474 const qpTestResult failResult = QP_TEST_RESULT_FAIL,
475 const std::string& failMessageTemplate = std::string(),
476 const bool renderFullSquare = false,
477 const bool splitRenderArea = false);
478
479 void createTestsForAllStages (const std::string& name,
480 const tcu::RGBA (&inputColors)[4],
481 const tcu::RGBA (&outputColors)[4],
482 const std::map<std::string, std::string>& testCodeFragments,
483 const SpecConstants& specConstants,
484 const PushConstants& pushConstants,
485 const GraphicsResources& resources,
486 const GraphicsInterfaces& interfaces,
487 const std::vector<std::string>& extensions,
488 VulkanFeatures vulkanFeatures,
489 tcu::TestCaseGroup* tests,
490 const qpTestResult failResult = QP_TEST_RESULT_FAIL,
491 const std::string& failMessageTemplate = std::string(),
492 const bool splitRenderArea = false);
493
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 ())494 inline void createTestsForAllStages (const std::string& name,
495 const tcu::RGBA (&inputColors)[4],
496 const tcu::RGBA (&outputColors)[4],
497 const std::map<std::string, std::string>& testCodeFragments,
498 tcu::TestCaseGroup* tests,
499 const qpTestResult failResult = QP_TEST_RESULT_FAIL,
500 const std::string& failMessageTemplate = std::string())
501 {
502 SpecConstants noSpecConstants;
503 PushConstants noPushConstants;
504 GraphicsResources noResources;
505 GraphicsInterfaces noInterfaces;
506 std::vector<std::string> noExtensions;
507
508 createTestsForAllStages(
509 name, inputColors, outputColors, testCodeFragments, noSpecConstants, noPushConstants,
510 noResources, noInterfaces, noExtensions, VulkanFeatures(),
511 tests, failResult, failMessageTemplate);
512 }
513
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 ())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 SpecConstants& specConstants,
519 tcu::TestCaseGroup* tests,
520 const qpTestResult failResult = QP_TEST_RESULT_FAIL,
521 const std::string& failMessageTemplate = std::string())
522 {
523 PushConstants noPushConstants;
524 GraphicsResources noResources;
525 GraphicsInterfaces noInterfaces;
526 std::vector<std::string> noExtensions;
527
528 createTestsForAllStages(
529 name, inputColors, outputColors, testCodeFragments, specConstants, noPushConstants,
530 noResources, noInterfaces, noExtensions, VulkanFeatures(),
531 tests, failResult, failMessageTemplate);
532 }
533
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 (),const bool splitRenderArea=false)534 inline void createTestsForAllStages (const std::string& name,
535 const tcu::RGBA (&inputColors)[4],
536 const tcu::RGBA (&outputColors)[4],
537 const std::map<std::string, std::string>& testCodeFragments,
538 const GraphicsResources& resources,
539 const std::vector<std::string>& extensions,
540 tcu::TestCaseGroup* tests,
541 VulkanFeatures vulkanFeatures = VulkanFeatures(),
542 const qpTestResult failResult = QP_TEST_RESULT_FAIL,
543 const std::string& failMessageTemplate = std::string(),
544 const bool splitRenderArea = false)
545 {
546 SpecConstants noSpecConstants;
547 PushConstants noPushConstants;
548 GraphicsInterfaces noInterfaces;
549
550 createTestsForAllStages(
551 name, inputColors, outputColors, testCodeFragments, noSpecConstants, noPushConstants,
552 resources, noInterfaces, extensions, vulkanFeatures,
553 tests, failResult, failMessageTemplate, splitRenderArea );
554 }
555
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 ())556 inline void createTestsForAllStages (const std::string& name,
557 const tcu::RGBA (&inputColors)[4],
558 const tcu::RGBA (&outputColors)[4],
559 const std::map<std::string, std::string>& testCodeFragments,
560 const GraphicsInterfaces interfaces,
561 const std::vector<std::string>& extensions,
562 tcu::TestCaseGroup* tests,
563 VulkanFeatures vulkanFeatures = VulkanFeatures(),
564 const qpTestResult failResult = QP_TEST_RESULT_FAIL,
565 const std::string& failMessageTemplate = std::string())
566 {
567 GraphicsResources noResources;
568 SpecConstants noSpecConstants;
569 PushConstants noPushConstants;
570
571 createTestsForAllStages(
572 name, inputColors, outputColors, testCodeFragments, noSpecConstants, noPushConstants,
573 noResources, interfaces, extensions, vulkanFeatures,
574 tests, failResult, failMessageTemplate);
575 }
576
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 ())577 inline void createTestsForAllStages (const std::string& name,
578 const tcu::RGBA (&inputColors)[4],
579 const tcu::RGBA (&outputColors)[4],
580 const std::map<std::string, std::string>& testCodeFragments,
581 const PushConstants& pushConstants,
582 const GraphicsResources& resources,
583 const std::vector<std::string>& extensions,
584 tcu::TestCaseGroup* tests,
585 VulkanFeatures vulkanFeatures = VulkanFeatures(),
586 const qpTestResult failResult = QP_TEST_RESULT_FAIL,
587 const std::string& failMessageTemplate = std::string())
588 {
589 SpecConstants noSpecConstants;
590 GraphicsInterfaces noInterfaces;
591
592 createTestsForAllStages(
593 name, inputColors, outputColors, testCodeFragments, noSpecConstants, pushConstants,
594 resources, noInterfaces, extensions, vulkanFeatures,
595 tests, failResult, failMessageTemplate);
596 }
597
598 // Sets up and runs a Vulkan pipeline, then spot-checks the resulting image.
599 // Feeds the pipeline a set of colored triangles, which then must occur in the
600 // rendered image. The surface is cleared before executing the pipeline, so
601 // whatever the shaders draw can be directly spot-checked.
602 tcu::TestStatus runAndVerifyDefaultPipeline (Context& context, InstanceContext instance);
603
604 // Use the instance context in the UnusedVariableContext to run the function above.
605 tcu::TestStatus runAndVerifyUnusedVariablePipeline (Context &context, UnusedVariableContext unusedVariableContext);
606
607 // Adds a new test to group using custom fragments for the tessellation-control
608 // stage and passthrough fragments for all other stages. Uses default colors
609 // for input and expected output.
610 void addTessCtrlTest (tcu::TestCaseGroup* group, const char* name, const std::map<std::string, std::string>& fragments);
611
612 // Given the original 32-bit float value, computes the corresponding 16-bit
613 // float value under the given rounding mode flags and compares with the
614 // returned 16-bit float value. Returns true if they are considered as equal.
615 //
616 // The following equivalence criteria are respected:
617 // * Positive and negative zeros are considered equivalent.
618 // * Denormalized floats are allowed to be flushed to zeros, including
619 // * Inputted 32bit denormalized float
620 // * Generated 16bit denormalized float
621 // * Different bit patterns of NaNs are allowed.
622 // * For the rest, require exactly the same bit pattern.
623 bool compare16BitFloat (float original, deUint16 returned, RoundingModeFlags flags, tcu::TestLog& log);
624
625 // Given the original 16-bit float value, computes the corresponding 32-bit
626 // float value and compares with the returned 32-bit float value.
627 // Returns true if they are considered as equal.
628 //
629 // The following equivalence criteria are respected:
630 // * Positive and negative zeros are considered equivalent.
631 // * Denormalized floats are allowed to be flushed to zeros, including
632 // * Inputted 16bit denormalized float
633 // * Generated 32bit denormalized float
634 // * Different bit patterns of NaNs are allowed.
635 // * For the rest, require exactly the same bit pattern.
636 bool compare16BitFloat (deUint16 returned, float original, tcu::TestLog& log);
637 bool compare16BitFloat (deFloat16 original, deFloat16 returned, std::string& error);
638
639 // Given the original 64-bit float value, computes the corresponding 16-bit
640 // float value under the given rounding mode flags and compares with the
641 // returned 16-bit float value. Returns true if they are considered as equal.
642 //
643 // The following equivalence criteria are respected:
644 // * Positive and negative zeros are considered equivalent.
645 // * Denormalized floats are allowed to be flushed to zeros, including
646 // * Inputted 64bit denormalized float
647 // * Generated 16bit denormalized float
648 // * Different bit patterns of NaNs are allowed.
649 // * For the rest, require exactly the same bit pattern.
650 bool compare16BitFloat64 (double original, deUint16 returned, RoundingModeFlags flags, tcu::TestLog& log);
651
652 // Compare the returned 32-bit float against its expected value.
653 //
654 // The following equivalence criteria are respected:
655 // * Denormalized floats are allowed to be flushed to zeros, including
656 // * The expected value itself is a denormalized float
657 // * The expected value is a denormalized float if converted to 16bit
658 // * Different bit patterns of NaNs/Infs are allowed.
659 // * For the rest, use C++ float equivalence check.
660 bool compare32BitFloat (float expected, float returned, tcu::TestLog& log);
661
662 // Compare the returned 64-bit float against its expected value.
663 //
664 // The following equivalence criteria are respected:
665 // * Denormalized floats are allowed to be flushed to zeros, including
666 // * The expected value itself is a denormalized float
667 // * The expected value is a denormalized float if converted to 16bit
668 // * Different bit patterns of NaNs/Infs are allowed.
669 // * For the rest, use C++ float equivalence check.
670 bool compare64BitFloat (double expected, double returned, tcu::TestLog& log);
671
672 } // SpirVAssembly
673 } // vkt
674
675 #endif // _VKTSPVASMGRAPHICSSHADERTESTUTIL_HPP
676