1f0f020f9a1d930bd0247b75b92c8a82f3ec56dd
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / spirv_assembly / vktSpvAsmGraphicsShaderTestUtil.hpp
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
95                                                         GraphicsResources()
96                                                                 : verifyIO      (DE_NULL)
97                                                         {}
98 };
99
100 // Interface data type.
101 struct IFDataType
102 {
103                                                 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
111                                                 IFDataType                      (const IFDataType& that)
112                                                         : numElements   (that.numElements)
113                                                         , elementType   (that.elementType)
114                                                 {}
115
116         deUint32                        getElementNumBytes      (void) const;
117         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
125         bool                            elementIs32bit          (void) const { return elementType < NUMBERTYPE_END32; }
126         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:
138                                                 GraphicsInterfaces      ()
139                                                         : rndMode       (static_cast<RoundingModeFlags>(0))
140                                                 {}
141
142                                                 GraphicsInterfaces      (const GraphicsInterfaces& that)
143                                                         : inputs        (that.inputs)
144                                                         , outputs       (that.outputs)
145                                                         , rndMode       (that.rndMode)
146                                                 {}
147
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
156         const IFDataType&       getInputType            (void) const
157                                                 {
158                                                         DE_ASSERT(inputs.size() == 1);
159                                                         return inputs.front().first;
160                                                 }
161
162         const IFDataType&       getOutputType           (void) const
163                                                 {
164                                                         DE_ASSERT(outputs.size() == 1);
165                                                         return outputs.front().first;
166                                                 }
167
168         const BufferSp&         getInputBuffer          (void) const
169                                                 {
170                                                         DE_ASSERT(inputs.size() == 1);
171                                                         return inputs.front().second;
172                                                 }
173
174         const BufferSp&         getOutputBuffer         (void) const
175                                                 {
176                                                         DE_ASSERT(outputs.size() == 1);
177                                                         return outputs.front().second;
178                                                 }
179
180         bool                            empty                           (void) const
181                                                 {
182                                                         return inputs.size() == 0;
183                                                 }
184
185         void                            setRoundingMode         (RoundingModeFlags flag)
186                                                 {
187                                                         rndMode = flag;
188                                                 }
189         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:
209                                                         PushConstants (void)
210                                                         {}
211
212                                                         PushConstants (const PushConstants& that)
213                                                                 : pcs   (that.pcs)
214                                                         {}
215
216         void                                    setPushConstant (const BufferSp& pc)
217                                                         {
218                                                                 pcs.clear();
219                                                                 pcs.push_back(pc);
220                                                         }
221
222         bool                                    empty (void) const
223                                                         {
224                                                                 return pcs.empty();
225                                                         }
226
227         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         ExtensionFeatures                                               requestedExtensionFeatures;
258         PushConstants                                                   pushConstants;
259         // Possible resources used by the graphics pipeline.
260         // If it is not empty, a single descriptor set (number 0) will be allocated
261         // to point to all resources specified. Binding numbers are allocated in
262         // accord with the resources' order in the vector; outputs are allocated
263         // after inputs.
264         GraphicsResources                                               resources;
265         // Possible interface variables use by the graphics pipeline.
266         // If it is not empty, input/output variables will be set up for shader stages
267         // in the test. Both the input and output variable will take location #2 in the
268         // pipeline for all stages, except that the output variable in the fragment
269         // stage will take location #1.
270         GraphicsInterfaces                                              interfaces;
271         qpTestResult                                                    failResult;
272         std::string                                                             failMessageTemplate;    //!< ${reason} in the template will be replaced with a detailed failure message
273
274         InstanceContext (const tcu::RGBA                                                        (&inputs)[4],
275                                          const tcu::RGBA                                                        (&outputs)[4],
276                                          const std::map<std::string, std::string>&      testCodeFragments_,
277                                          const StageToSpecConstantMap&                          specConstants_,
278                                          const PushConstants&                                           pushConsants_,
279                                          const GraphicsResources&                                       resources_,
280                                          const GraphicsInterfaces&                                      interfaces_,
281                                          const std::vector<std::string>&                        extensions_,
282                                          const std::vector<std::string>&                        features_,
283                                          ExtensionFeatures                                                      extFeatures_);
284
285         InstanceContext (const InstanceContext& other);
286
287         std::string getSpecializedFailMessage (const std::string& failureReason);
288 };
289
290 // A description of a shader to be used for a single stage of the graphics pipeline.
291 struct ShaderElement
292 {
293         // The module that contains this shader entrypoint.
294         std::string                                     moduleName;
295
296         // The name of the entrypoint.
297         std::string                                     entryName;
298
299         // Which shader stage this entry point represents.
300         vk::VkShaderStageFlagBits       stage;
301
302         ShaderElement (const std::string& moduleName_, const std::string& entryPoint_, vk::VkShaderStageFlagBits shaderStage_);
303 };
304
305 template <typename T>
306 const std::string numberToString (T number)
307 {
308         std::stringstream ss;
309         ss << number;
310         return ss.str();
311 }
312
313 // Performs a bitwise copy of source to the destination type Dest.
314 template <typename Dest, typename Src>
315 Dest bitwiseCast(Src source)
316 {
317   Dest dest;
318   DE_STATIC_ASSERT(sizeof(source) == sizeof(dest));
319   deMemcpy(&dest, &source, sizeof(dest));
320   return dest;
321 }
322
323 template<typename T>    T                       randomScalar    (de::Random& rnd, T minValue, T maxValue);
324 template<> inline               float           randomScalar    (de::Random& rnd, float minValue, float maxValue)               { return rnd.getFloat(minValue, maxValue);      }
325 template<> inline               deInt32         randomScalar    (de::Random& rnd, deInt32 minValue, deInt32 maxValue)   { return rnd.getInt(minValue, maxValue);        }
326
327
328 void getDefaultColors (tcu::RGBA (&colors)[4]);
329
330 void getHalfColorsFullAlpha (tcu::RGBA (&colors)[4]);
331
332 void getInvertedDefaultColors (tcu::RGBA (&colors)[4]);
333
334 // Creates fragments that specialize into a simple pass-through shader (of any kind).
335 std::map<std::string, std::string> passthruFragments(void);
336
337 void createCombinedModule(vk::SourceCollections& dst, InstanceContext);
338
339 // This has two shaders of each stage. The first
340 // is a passthrough, the second inverts the color.
341 void createMultipleEntries(vk::SourceCollections& dst, InstanceContext);
342
343 // Turns a statically sized array of ShaderElements into an instance-context
344 // by setting up the mapping of modules to their contained shaders and stages.
345 // The inputs and expected outputs are given by inputColors and outputColors
346 template<size_t N>
347 InstanceContext createInstanceContext (const ShaderElement                                                      (&elements)[N],
348                                                                            const tcu::RGBA                                                              (&inputColors)[4],
349                                                                            const tcu::RGBA                                                              (&outputColors)[4],
350                                                                            const std::map<std::string, std::string>&    testCodeFragments,
351                                                                            const StageToSpecConstantMap&                                specConstants,
352                                                                            const PushConstants&                                                 pushConstants,
353                                                                            const GraphicsResources&                                             resources,
354                                                                            const GraphicsInterfaces&                                    interfaces,
355                                                                            const std::vector<std::string>&                              extensions,
356                                                                            const std::vector<std::string>&                              features,
357                                                                            ExtensionFeatures                                                    extensionFeatures,
358                                                                            const qpTestResult                                                   failResult                      = QP_TEST_RESULT_FAIL,
359                                                                            const std::string&                                                   failMessageTemplate     = std::string())
360 {
361         InstanceContext ctx (inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources, interfaces, extensions, features, extensionFeatures);
362         for (size_t i = 0; i < N; ++i)
363         {
364                 ctx.moduleMap[elements[i].moduleName].push_back(std::make_pair(elements[i].entryName, elements[i].stage));
365                 ctx.requiredStages = static_cast<VkShaderStageFlagBits>(ctx.requiredStages | elements[i].stage);
366         }
367         ctx.failResult                          = failResult;
368         if (!failMessageTemplate.empty())
369                 ctx.failMessageTemplate = failMessageTemplate;
370         return ctx;
371 }
372
373 // The same as createInstanceContext above, without extensions, spec constants, and resources.
374 template<size_t N>
375 inline InstanceContext createInstanceContext (const ShaderElement                                               (&elements)[N],
376                                                                                           tcu::RGBA                                                                     (&inputColors)[4],
377                                                                                           const tcu::RGBA                                                       (&outputColors)[4],
378                                                                                           const std::map<std::string, std::string>&     testCodeFragments)
379 {
380         return createInstanceContext(elements, inputColors, outputColors, testCodeFragments,
381                                                                  StageToSpecConstantMap(), PushConstants(), GraphicsResources(),
382                                                                  GraphicsInterfaces(), std::vector<std::string>(), std::vector<std::string>(),
383                                                                  ExtensionFeatures());
384 }
385
386 // The same as createInstanceContext above, but with default colors.
387 template<size_t N>
388 InstanceContext createInstanceContext (const ShaderElement                                                      (&elements)[N],
389                                                                            const std::map<std::string, std::string>&    testCodeFragments)
390 {
391         tcu::RGBA defaultColors[4];
392         getDefaultColors(defaultColors);
393         return createInstanceContext(elements, defaultColors, defaultColors, testCodeFragments);
394 }
395
396
397 void createTestsForAllStages (const std::string&                                                name,
398                                                           const tcu::RGBA                                                       (&inputColors)[4],
399                                                           const tcu::RGBA                                                       (&outputColors)[4],
400                                                           const std::map<std::string, std::string>&     testCodeFragments,
401                                                           const std::vector<deInt32>&                           specConstants,
402                                                           const PushConstants&                                          pushConstants,
403                                                           const GraphicsResources&                                      resources,
404                                                           const GraphicsInterfaces&                                     interfaces,
405                                                           const std::vector<std::string>&                       extensions,
406                                                           const std::vector<std::string>&                       features,
407                                                           ExtensionFeatures                                                     extensionFeatures,
408                                                           tcu::TestCaseGroup*                                           tests,
409                                                           const qpTestResult                                            failResult                      = QP_TEST_RESULT_FAIL,
410                                                           const std::string&                                            failMessageTemplate     = std::string());
411
412 inline void createTestsForAllStages (const std::string&                                                 name,
413                                                                          const tcu::RGBA                                                        (&inputColors)[4],
414                                                                          const tcu::RGBA                                                        (&outputColors)[4],
415                                                                          const std::map<std::string, std::string>&      testCodeFragments,
416                                                                          tcu::TestCaseGroup*                                            tests,
417                                                                          const qpTestResult                                                     failResult                      = QP_TEST_RESULT_FAIL,
418                                                                          const std::string&                                                     failMessageTemplate     = std::string())
419 {
420         std::vector<deInt32>            noSpecConstants;
421         PushConstants                           noPushConstants;
422         GraphicsResources                       noResources;
423         GraphicsInterfaces                      noInterfaces;
424         std::vector<std::string>        noExtensions;
425         std::vector<std::string>        noFeatures;
426
427         createTestsForAllStages(
428                         name, inputColors, outputColors, testCodeFragments, noSpecConstants, noPushConstants,
429                         noResources, noInterfaces, noExtensions, noFeatures, ExtensionFeatures(),
430                         tests, failResult, failMessageTemplate);
431 }
432
433 inline void createTestsForAllStages (const std::string&                                                 name,
434                                                                          const tcu::RGBA                                                        (&inputColors)[4],
435                                                                          const tcu::RGBA                                                        (&outputColors)[4],
436                                                                          const std::map<std::string, std::string>&      testCodeFragments,
437                                                                          const std::vector<deInt32>&                            specConstants,
438                                                                          tcu::TestCaseGroup*                                            tests,
439                                                                          const qpTestResult                                                     failResult                      = QP_TEST_RESULT_FAIL,
440                                                                          const std::string&                                                     failMessageTemplate     = std::string())
441 {
442         PushConstants                                   noPushConstants;
443         GraphicsResources                               noResources;
444         GraphicsInterfaces                              noInterfaces;
445         std::vector<std::string>                noExtensions;
446         std::vector<std::string>                noFeatures;
447
448         createTestsForAllStages(
449                         name, inputColors, outputColors, testCodeFragments, specConstants, noPushConstants,
450                         noResources, noInterfaces, noExtensions, noFeatures, ExtensionFeatures(),
451                         tests, failResult, failMessageTemplate);
452 }
453
454 inline void createTestsForAllStages (const std::string&                                                 name,
455                                                                          const tcu::RGBA                                                        (&inputColors)[4],
456                                                                          const tcu::RGBA                                                        (&outputColors)[4],
457                                                                          const std::map<std::string, std::string>&      testCodeFragments,
458                                                                          const GraphicsResources&                                       resources,
459                                                                          const std::vector<std::string>&                        extensions,
460                                                                          tcu::TestCaseGroup*                                            tests,
461                                                                          ExtensionFeatures                                                      extensionFeatures       = ExtensionFeatures(),
462                                                                          const qpTestResult                                                     failResult                      = QP_TEST_RESULT_FAIL,
463                                                                          const std::string&                                                     failMessageTemplate     = std::string())
464 {
465         std::vector<deInt32>            noSpecConstants;
466         PushConstants                           noPushConstants;
467         GraphicsInterfaces                      noInterfaces;
468         std::vector<std::string>        noFeatures;
469
470         createTestsForAllStages(
471                         name, inputColors, outputColors, testCodeFragments, noSpecConstants, noPushConstants,
472                         resources, noInterfaces, extensions, noFeatures, extensionFeatures,
473                         tests, failResult, failMessageTemplate);
474 }
475
476 inline void createTestsForAllStages (const std::string& name,
477                                                                          const tcu::RGBA                                                        (&inputColors)[4],
478                                                                          const tcu::RGBA                                                        (&outputColors)[4],
479                                                                          const std::map<std::string, std::string>&      testCodeFragments,
480                                                                          const GraphicsInterfaces                                       interfaces,
481                                                                          const std::vector<std::string>&                        extensions,
482                                                                          tcu::TestCaseGroup*                                            tests,
483                                                                          ExtensionFeatures                                                      extensionFeatures       = ExtensionFeatures(),
484                                                                          const qpTestResult                                                     failResult                      = QP_TEST_RESULT_FAIL,
485                                                                          const std::string&                                                     failMessageTemplate     = std::string())
486 {
487         GraphicsResources                       noResources;
488         std::vector<deInt32>            noSpecConstants;
489         std::vector<std::string>        noFeatures;
490         PushConstants                           noPushConstants;
491
492         createTestsForAllStages(
493                         name, inputColors, outputColors, testCodeFragments, noSpecConstants, noPushConstants,
494                         noResources, interfaces, extensions, noFeatures, extensionFeatures,
495                         tests, failResult, failMessageTemplate);
496 }
497
498 inline void createTestsForAllStages (const std::string& name,
499                                                                          const tcu::RGBA                                                        (&inputColors)[4],
500                                                                          const tcu::RGBA                                                        (&outputColors)[4],
501                                                                          const std::map<std::string, std::string>&      testCodeFragments,
502                                                                          const PushConstants&                                           pushConstants,
503                                                                          const GraphicsResources&                                       resources,
504                                                                          const std::vector<std::string>&                        extensions,
505                                                                          tcu::TestCaseGroup*                                            tests,
506                                                                          ExtensionFeatures                                                      extensionFeatures       = ExtensionFeatures(),
507                                                                          const qpTestResult                                                     failResult                      = QP_TEST_RESULT_FAIL,
508                                                                          const std::string&                                                     failMessageTemplate     = std::string())
509 {
510         std::vector<deInt32>                    noSpecConstants;
511         GraphicsInterfaces                              noInterfaces;
512         std::vector<std::string>                noFeatures;
513
514         createTestsForAllStages(
515                         name, inputColors, outputColors, testCodeFragments, noSpecConstants, pushConstants,
516                         resources, noInterfaces, extensions, noFeatures, extensionFeatures,
517                         tests, failResult, failMessageTemplate);
518 }
519
520 // Sets up and runs a Vulkan pipeline, then spot-checks the resulting image.
521 // Feeds the pipeline a set of colored triangles, which then must occur in the
522 // rendered image.  The surface is cleared before executing the pipeline, so
523 // whatever the shaders draw can be directly spot-checked.
524 tcu::TestStatus runAndVerifyDefaultPipeline (Context& context, InstanceContext instance);
525
526 // Adds a new test to group using custom fragments for the tessellation-control
527 // stage and passthrough fragments for all other stages.  Uses default colors
528 // for input and expected output.
529 void addTessCtrlTest(tcu::TestCaseGroup* group, const char* name, const std::map<std::string, std::string>& fragments);
530
531 // Given the original 32-bit float value, computes the corresponding 16-bit
532 // float value under the given rounding mode flags and compares with the
533 // returned 16-bit float value. Returns true if they are considered as equal.
534 //
535 // The following equivalence criteria are respected:
536 // * Positive and negative zeros are considered equivalent.
537 // * Denormalized floats are allowed to be flushed to zeros.
538 // * Different bit patterns of NaNs are allowed.
539 // * For the rest, require exactly the same bit pattern.
540 bool compare16BitFloat (float original, deUint16 returned, RoundingModeFlags flags, tcu::TestLog& log);
541
542 // Compare the returned 32-bit float against its expected value.
543 //
544 // The following equivalence criteria are respected:
545 // * Denormalized floats are allowed to be flushed to zeros.
546 // * Different bit patterns of NaNs/Infs are allowed.
547 // * For the rest, use C++ float equivalence check.
548 bool compare32BitFloat (float expected, float returned, tcu::TestLog& log);
549
550 } // SpirVAssembly
551 } // vkt
552
553 #endif // _VKTSPVASMGRAPHICSSHADERTESTUTIL_HPP