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 bool splitRenderArea; // Split render into multiple submissions.
289
290 InstanceContext (const tcu::RGBA (&inputs)[4],
291 const tcu::RGBA (&outputs)[4],
292 const std::map<std::string, std::string>& testCodeFragments_,
293 const StageToSpecConstantMap& specConstants_,
294 const PushConstants& pushConsants_,
295 const GraphicsResources& resources_,
296 const GraphicsInterfaces& interfaces_,
297 const std::vector<std::string>& extensions_,
298 VulkanFeatures vulkanFeatures_,
299 VkShaderStageFlags customizedStages_);
300
301 InstanceContext (const InstanceContext& other);
302
303 std::string getSpecializedFailMessage (const std::string& failureReason);
304 };
305
306 enum ShaderTask
307 {
308 SHADER_TASK_NONE = 0,
309 SHADER_TASK_NORMAL,
310 SHADER_TASK_UNUSED_VAR,
311 SHADER_TASK_UNUSED_FUNC,
312 SHADER_TASK_LAST
313 };
314
315 enum ShaderTaskIndex
316 {
317 SHADER_TASK_INDEX_VERTEX = 0,
318 SHADER_TASK_INDEX_GEOMETRY = 1,
319 SHADER_TASK_INDEX_TESS_CONTROL = 2,
320 SHADER_TASK_INDEX_TESS_EVAL = 3,
321 SHADER_TASK_INDEX_FRAGMENT = 4,
322 SHADER_TASK_INDEX_LAST = 5
323 };
324
325 typedef ShaderTask ShaderTaskArray[SHADER_TASK_INDEX_LAST];
326
327 struct UnusedVariableContext
328 {
329 InstanceContext instanceContext;
330 ShaderTaskArray shaderTasks;
331 VariableLocation variableLocation;
332
UnusedVariableContextvkt::SpirVAssembly::UnusedVariableContext333 UnusedVariableContext(const InstanceContext& ctx, const ShaderTaskArray& tasks, const VariableLocation& location)
334 : instanceContext(ctx), shaderTasks(), variableLocation(location)
335 {
336 deMemcpy(shaderTasks, tasks, sizeof(tasks));
337 }
338 };
339
340 // A description of a shader to be used for a single stage of the graphics pipeline.
341 struct ShaderElement
342 {
343 // The module that contains this shader entrypoint.
344 std::string moduleName;
345
346 // The name of the entrypoint.
347 std::string entryName;
348
349 // Which shader stage this entry point represents.
350 vk::VkShaderStageFlagBits stage;
351
352 ShaderElement (const std::string& moduleName_, const std::string& entryPoint_, vk::VkShaderStageFlagBits shaderStage_);
353 };
354
355 template <typename T>
numberToString(T number)356 const std::string numberToString (T number)
357 {
358 std::stringstream ss;
359 ss << number;
360 return ss.str();
361 }
362
363 void getDefaultColors (tcu::RGBA (&colors)[4]);
364
365 void getHalfColorsFullAlpha (tcu::RGBA (&colors)[4]);
366
367 void getInvertedDefaultColors (tcu::RGBA (&colors)[4]);
368
369 // Creates fragments that specialize into a simple pass-through shader (of any kind).
370 std::map<std::string, std::string> passthruFragments (void);
371
372 // Creates a combined shader module based on VkShaderStageFlagBits defined in InstanceContext.
373 void createCombinedModule (vk::SourceCollections& dst, InstanceContext ctx);
374
375 // Creates shaders with unused variables based on the UnusedVariableContext.
376 void createUnusedVariableModules (vk::SourceCollections& dst, UnusedVariableContext ctx);
377
378 // This has two shaders of each stage. The first
379 // is a passthrough, the second inverts the color.
380 void createMultipleEntries (vk::SourceCollections& dst, InstanceContext);
381
382 // Turns a vector of ShaderElements into an instance-context by setting up the mapping of modules
383 // to their contained shaders and stages. The inputs and expected outputs are given by inputColors
384 // and outputColors
385 InstanceContext createInstanceContext (const std::vector<ShaderElement>& elements,
386 const tcu::RGBA (&inputColors)[4],
387 const tcu::RGBA (&outputColors)[4],
388 const std::map<std::string, std::string>& testCodeFragments,
389 const StageToSpecConstantMap& specConstants,
390 const PushConstants& pushConstants,
391 const GraphicsResources& resources,
392 const GraphicsInterfaces& interfaces,
393 const std::vector<std::string>& extensions,
394 VulkanFeatures vulkanFeatures,
395 VkShaderStageFlags customizedStages,
396 const qpTestResult failResult = QP_TEST_RESULT_FAIL,
397 const std::string& failMessageTemplate = std::string());
398
399 // Same as above but using a statically sized array.
400 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 ())401 inline InstanceContext createInstanceContext (const ShaderElement (&elements)[N],
402 const tcu::RGBA (&inputColors)[4],
403 const tcu::RGBA (&outputColors)[4],
404 const std::map<std::string, std::string>& testCodeFragments,
405 const StageToSpecConstantMap& specConstants,
406 const PushConstants& pushConstants,
407 const GraphicsResources& resources,
408 const GraphicsInterfaces& interfaces,
409 const std::vector<std::string>& extensions,
410 VulkanFeatures vulkanFeatures,
411 VkShaderStageFlags customizedStages,
412 const qpTestResult failResult = QP_TEST_RESULT_FAIL,
413 const std::string& failMessageTemplate = std::string())
414 {
415 std::vector<ShaderElement> elementsVector(elements, elements + N);
416 return createInstanceContext(elementsVector, inputColors, outputColors, testCodeFragments, specConstants, pushConstants,
417 resources, interfaces, extensions, vulkanFeatures, customizedStages, failResult, failMessageTemplate);
418 }
419
420 // The same as createInstanceContext above, without extensions, spec constants, and resources.
421 InstanceContext createInstanceContext (const std::vector<ShaderElement>& elements,
422 tcu::RGBA (&inputColors)[4],
423 const tcu::RGBA (&outputColors)[4],
424 const std::map<std::string, std::string>& testCodeFragments);
425
426 // Same as above, but using a statically sized array.
427 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)428 inline InstanceContext createInstanceContext (const ShaderElement (&elements)[N],
429 tcu::RGBA (&inputColors)[4],
430 const tcu::RGBA (&outputColors)[4],
431 const std::map<std::string, std::string>& testCodeFragments)
432 {
433 std::vector<ShaderElement> elementsVector(elements, elements + N);
434 return createInstanceContext(elementsVector, inputColors, outputColors, testCodeFragments);
435 }
436
437 // The same as createInstanceContext above, but with default colors.
438 InstanceContext createInstanceContext (const std::vector<ShaderElement>& elements,
439 const std::map<std::string, std::string>& testCodeFragments);
440
441 // Same as above, but using a statically sized array.
442 template<size_t N>
createInstanceContext(const ShaderElement (& elements)[N],const std::map<std::string,std::string> & testCodeFragments)443 inline InstanceContext createInstanceContext (const ShaderElement (&elements)[N],
444 const std::map<std::string, std::string>& testCodeFragments)
445 {
446 std::vector<ShaderElement> elementsVector(elements, elements + N);
447 return createInstanceContext(elementsVector, testCodeFragments);
448 }
449
450
451 // Create an unused variable context for the given combination.
452 UnusedVariableContext createUnusedVariableContext(const ShaderTaskArray& shaderTasks, const VariableLocation& location);
453
454 void addShaderCodeCustomVertex (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions);
455 void addShaderCodeCustomTessControl (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions);
456 void addShaderCodeCustomTessEval (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions);
457 void addShaderCodeCustomGeometry (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions);
458 void addShaderCodeCustomFragment (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions);
459
460 void createTestForStage (vk::VkShaderStageFlagBits stage,
461 const std::string& name,
462 const tcu::RGBA (&inputColors)[4],
463 const tcu::RGBA (&outputColors)[4],
464 const std::map<std::string, std::string>& testCodeFragments,
465 const SpecConstants& specConstants,
466 const PushConstants& pushConstants,
467 const GraphicsResources& resources,
468 const GraphicsInterfaces& interfaces,
469 const std::vector<std::string>& extensions,
470 VulkanFeatures vulkanFeatures,
471 tcu::TestCaseGroup* tests,
472 const qpTestResult failResult = QP_TEST_RESULT_FAIL,
473 const std::string& failMessageTemplate = std::string(),
474 const bool renderFullSquare = false,
475 const bool splitRenderArea = false);
476
477 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 SpecConstants& specConstants,
482 const PushConstants& pushConstants,
483 const GraphicsResources& resources,
484 const GraphicsInterfaces& interfaces,
485 const std::vector<std::string>& extensions,
486 VulkanFeatures vulkanFeatures,
487 tcu::TestCaseGroup* tests,
488 const qpTestResult failResult = QP_TEST_RESULT_FAIL,
489 const std::string& failMessageTemplate = std::string(),
490 const bool splitRenderArea = false);
491
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 ())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 tcu::TestCaseGroup* tests,
497 const qpTestResult failResult = QP_TEST_RESULT_FAIL,
498 const std::string& failMessageTemplate = std::string())
499 {
500 SpecConstants noSpecConstants;
501 PushConstants noPushConstants;
502 GraphicsResources noResources;
503 GraphicsInterfaces noInterfaces;
504 std::vector<std::string> noExtensions;
505
506 createTestsForAllStages(
507 name, inputColors, outputColors, testCodeFragments, noSpecConstants, noPushConstants,
508 noResources, noInterfaces, noExtensions, VulkanFeatures(),
509 tests, failResult, failMessageTemplate);
510 }
511
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 ())512 inline void createTestsForAllStages (const std::string& name,
513 const tcu::RGBA (&inputColors)[4],
514 const tcu::RGBA (&outputColors)[4],
515 const std::map<std::string, std::string>& testCodeFragments,
516 const SpecConstants& specConstants,
517 tcu::TestCaseGroup* tests,
518 const qpTestResult failResult = QP_TEST_RESULT_FAIL,
519 const std::string& failMessageTemplate = std::string())
520 {
521 PushConstants noPushConstants;
522 GraphicsResources noResources;
523 GraphicsInterfaces noInterfaces;
524 std::vector<std::string> noExtensions;
525
526 createTestsForAllStages(
527 name, inputColors, outputColors, testCodeFragments, specConstants, noPushConstants,
528 noResources, noInterfaces, noExtensions, VulkanFeatures(),
529 tests, failResult, failMessageTemplate);
530 }
531
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)532 inline void createTestsForAllStages (const std::string& name,
533 const tcu::RGBA (&inputColors)[4],
534 const tcu::RGBA (&outputColors)[4],
535 const std::map<std::string, std::string>& testCodeFragments,
536 const GraphicsResources& resources,
537 const std::vector<std::string>& extensions,
538 tcu::TestCaseGroup* tests,
539 VulkanFeatures vulkanFeatures = VulkanFeatures(),
540 const qpTestResult failResult = QP_TEST_RESULT_FAIL,
541 const std::string& failMessageTemplate = std::string(),
542 const bool splitRenderArea = false)
543 {
544 SpecConstants noSpecConstants;
545 PushConstants noPushConstants;
546 GraphicsInterfaces noInterfaces;
547
548 createTestsForAllStages(
549 name, inputColors, outputColors, testCodeFragments, noSpecConstants, noPushConstants,
550 resources, noInterfaces, extensions, vulkanFeatures,
551 tests, failResult, failMessageTemplate, splitRenderArea );
552 }
553
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 ())554 inline void createTestsForAllStages (const std::string& name,
555 const tcu::RGBA (&inputColors)[4],
556 const tcu::RGBA (&outputColors)[4],
557 const std::map<std::string, std::string>& testCodeFragments,
558 const GraphicsInterfaces interfaces,
559 const std::vector<std::string>& extensions,
560 tcu::TestCaseGroup* tests,
561 VulkanFeatures vulkanFeatures = VulkanFeatures(),
562 const qpTestResult failResult = QP_TEST_RESULT_FAIL,
563 const std::string& failMessageTemplate = std::string())
564 {
565 GraphicsResources noResources;
566 SpecConstants noSpecConstants;
567 PushConstants noPushConstants;
568
569 createTestsForAllStages(
570 name, inputColors, outputColors, testCodeFragments, noSpecConstants, noPushConstants,
571 noResources, interfaces, extensions, vulkanFeatures,
572 tests, failResult, failMessageTemplate);
573 }
574
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 ())575 inline void createTestsForAllStages (const std::string& name,
576 const tcu::RGBA (&inputColors)[4],
577 const tcu::RGBA (&outputColors)[4],
578 const std::map<std::string, std::string>& testCodeFragments,
579 const PushConstants& pushConstants,
580 const GraphicsResources& resources,
581 const std::vector<std::string>& extensions,
582 tcu::TestCaseGroup* tests,
583 VulkanFeatures vulkanFeatures = VulkanFeatures(),
584 const qpTestResult failResult = QP_TEST_RESULT_FAIL,
585 const std::string& failMessageTemplate = std::string())
586 {
587 SpecConstants noSpecConstants;
588 GraphicsInterfaces noInterfaces;
589
590 createTestsForAllStages(
591 name, inputColors, outputColors, testCodeFragments, noSpecConstants, pushConstants,
592 resources, noInterfaces, extensions, vulkanFeatures,
593 tests, failResult, failMessageTemplate);
594 }
595
596 // Sets up and runs a Vulkan pipeline, then spot-checks the resulting image.
597 // Feeds the pipeline a set of colored triangles, which then must occur in the
598 // rendered image. The surface is cleared before executing the pipeline, so
599 // whatever the shaders draw can be directly spot-checked.
600 tcu::TestStatus runAndVerifyDefaultPipeline (Context& context, InstanceContext instance);
601
602 // Use the instance context in the UnusedVariableContext to run the function above.
603 tcu::TestStatus runAndVerifyUnusedVariablePipeline (Context &context, UnusedVariableContext unusedVariableContext);
604
605 // Adds a new test to group using custom fragments for the tessellation-control
606 // stage and passthrough fragments for all other stages. Uses default colors
607 // for input and expected output.
608 void addTessCtrlTest (tcu::TestCaseGroup* group, const char* name, const std::map<std::string, std::string>& fragments);
609
610 // Given the original 32-bit float value, computes the corresponding 16-bit
611 // float value under the given rounding mode flags and compares with the
612 // returned 16-bit float value. Returns true if they are considered as equal.
613 //
614 // The following equivalence criteria are respected:
615 // * Positive and negative zeros are considered equivalent.
616 // * Denormalized floats are allowed to be flushed to zeros, including
617 // * Inputted 32bit denormalized float
618 // * Generated 16bit denormalized float
619 // * Different bit patterns of NaNs are allowed.
620 // * For the rest, require exactly the same bit pattern.
621 bool compare16BitFloat (float original, deUint16 returned, RoundingModeFlags flags, tcu::TestLog& log);
622
623 // Given the original 16-bit float value, computes the corresponding 32-bit
624 // float value and compares with the returned 32-bit float value.
625 // Returns true if they are considered as equal.
626 //
627 // The following equivalence criteria are respected:
628 // * Positive and negative zeros are considered equivalent.
629 // * Denormalized floats are allowed to be flushed to zeros, including
630 // * Inputted 16bit denormalized float
631 // * Generated 32bit denormalized float
632 // * Different bit patterns of NaNs are allowed.
633 // * For the rest, require exactly the same bit pattern.
634 bool compare16BitFloat (deUint16 returned, float original, tcu::TestLog& log);
635 bool compare16BitFloat (deFloat16 original, deFloat16 returned, std::string& error);
636
637 // Given the original 64-bit float value, computes the corresponding 16-bit
638 // float value under the given rounding mode flags and compares with the
639 // returned 16-bit float value. Returns true if they are considered as equal.
640 //
641 // The following equivalence criteria are respected:
642 // * Positive and negative zeros are considered equivalent.
643 // * Denormalized floats are allowed to be flushed to zeros, including
644 // * Inputted 64bit denormalized float
645 // * Generated 16bit denormalized float
646 // * Different bit patterns of NaNs are allowed.
647 // * For the rest, require exactly the same bit pattern.
648 bool compare16BitFloat64 (double original, deUint16 returned, RoundingModeFlags flags, tcu::TestLog& log);
649
650 // Compare the returned 32-bit float against its expected value.
651 //
652 // The following equivalence criteria are respected:
653 // * Denormalized floats are allowed to be flushed to zeros, including
654 // * The expected value itself is a denormalized float
655 // * The expected value is a denormalized float if converted to 16bit
656 // * Different bit patterns of NaNs/Infs are allowed.
657 // * For the rest, use C++ float equivalence check.
658 bool compare32BitFloat (float expected, float returned, tcu::TestLog& log);
659
660 // Compare the returned 64-bit float against its expected value.
661 //
662 // The following equivalence criteria are respected:
663 // * Denormalized floats are allowed to be flushed to zeros, including
664 // * The expected value itself is a denormalized float
665 // * The expected value is a denormalized float if converted to 16bit
666 // * Different bit patterns of NaNs/Infs are allowed.
667 // * For the rest, use C++ float equivalence check.
668 bool compare64BitFloat (double expected, double returned, tcu::TestLog& log);
669
670 } // SpirVAssembly
671 } // vkt
672
673 #endif // _VKTSPVASMGRAPHICSSHADERTESTUTIL_HPP
674