Check memory model support in volatile atomic tests
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / spirv_assembly / vktSpvAsmUtils.hpp
1 #ifndef _VKTSPVASMUTILS_HPP
2 #define _VKTSPVASMUTILS_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 Utilities for Vulkan SPIR-V assembly tests
24  *//*--------------------------------------------------------------------*/
25
26 #include "vkDefs.hpp"
27 #include "vkMemUtil.hpp"
28 #include "vkRef.hpp"
29 #include "vkTypeUtil.hpp"
30 #include "vktTestCase.hpp"
31
32 #include "deMemory.h"
33 #include "deUniquePtr.hpp"
34 #include "deSharedPtr.hpp"
35 #include "deRandom.hpp"
36 #include "deFloat16.h"
37
38 #include <string>
39 #include <vector>
40
41 namespace vkt
42 {
43 namespace SpirVAssembly
44 {
45
46 #define SPIRV_ASSEMBLY_TYPES                                                                                                                                                            \
47         "%void = OpTypeVoid\n"                                                                                                                                                                  \
48         "%bool = OpTypeBool\n"                                                                                                                                                                  \
49                                                                                                                                                                                                                         \
50         "%i32 = OpTypeInt 32 1\n"                                                                                                                                                               \
51         "%u32 = OpTypeInt 32 0\n"                                                                                                                                                               \
52                                                                                                                                                                                                                         \
53         "%f32 = OpTypeFloat 32\n"                                                                                                                                                               \
54         "%v2i32 = OpTypeVector %i32 2\n"                                                                                                                                                \
55         "%v2u32 = OpTypeVector %u32 2\n"                                                                                                                                                \
56         "%v2f32 = OpTypeVector %f32 2\n"                                                                                                                                                \
57         "%v3i32 = OpTypeVector %i32 3\n"                                                                                                                                                \
58         "%v3u32 = OpTypeVector %u32 3\n"                                                                                                                                                \
59         "%v3f32 = OpTypeVector %f32 3\n"                                                                                                                                                \
60         "%v4i32 = OpTypeVector %i32 4\n"                                                                                                                                                \
61         "%v4u32 = OpTypeVector %u32 4\n"                                                                                                                                                \
62         "%v4f32 = OpTypeVector %f32 4\n"                                                                                                                                                \
63         "%v4bool = OpTypeVector %bool 4\n"                                                                                                                                              \
64                                                                                                                                                                                                                         \
65         "%v4f32_v4f32_function = OpTypeFunction %v4f32 %v4f32\n"                                                                        \
66         "%bool_function = OpTypeFunction %bool\n"                                                                                                                               \
67         "%voidf = OpTypeFunction %void\n"                                                                                                                                                       \
68                                                                                                                                                                                                                         \
69         "%ip_f32 = OpTypePointer Input %f32\n"                                                                                                                                  \
70         "%ip_i32 = OpTypePointer Input %i32\n"                                                                                                                                  \
71         "%ip_u32 = OpTypePointer Input %u32\n"                                                                                                                                  \
72         "%ip_v2f32 = OpTypePointer Input %v2f32\n"                                                                                                                              \
73         "%ip_v2i32 = OpTypePointer Input %v2i32\n"                                                                                                                              \
74         "%ip_v2u32 = OpTypePointer Input %v2u32\n"                                                                                                                              \
75         "%ip_v3f32 = OpTypePointer Input %v3f32\n"                                                                                                                              \
76         "%ip_v4f32 = OpTypePointer Input %v4f32\n"                                                                                                                              \
77         "%ip_v4i32 = OpTypePointer Input %v4i32\n"                                                                                                                              \
78         "%ip_v4u32 = OpTypePointer Input %v4u32\n"                                                                                                                              \
79                                                                                                                                                                                                                         \
80         "%op_f32 = OpTypePointer Output %f32\n"                                                                                                                                 \
81         "%op_i32 = OpTypePointer Output %i32\n"                                                                                                                                 \
82         "%op_u32 = OpTypePointer Output %u32\n"                                                                                                                                 \
83         "%op_v2f32 = OpTypePointer Output %v2f32\n"                                                                                                                             \
84         "%op_v2i32 = OpTypePointer Output %v2i32\n"                                                                                                                             \
85         "%op_v2u32 = OpTypePointer Output %v2u32\n"                                                                                                                             \
86         "%op_v4f32 = OpTypePointer Output %v4f32\n"                                                                                                                             \
87         "%op_v4i32 = OpTypePointer Output %v4i32\n"                                                                                                                             \
88         "%op_v4u32 = OpTypePointer Output %v4u32\n"                                                                                                                             \
89                                                                                                                                                                                                                         \
90         "%fp_f32   = OpTypePointer Function %f32\n"                                                                                                                             \
91         "%fp_i32   = OpTypePointer Function %i32\n"                                                                                                                             \
92         "%fp_v4f32 = OpTypePointer Function %v4f32\n"                                                                                                                   \
93
94 #define SPIRV_ASSEMBLY_CONSTANTS                                                                                                                                                        \
95         "%c_f32_1 = OpConstant %f32 1.0\n"                                                                                                                                              \
96         "%c_f32_0 = OpConstant %f32 0.0\n"                                                                                                                                              \
97         "%c_f32_0_5 = OpConstant %f32 0.5\n"                                                                                                                                    \
98         "%c_f32_n1  = OpConstant %f32 -1.\n"                                                                                                                                    \
99         "%c_f32_7 = OpConstant %f32 7.0\n"                                                                                                                                              \
100         "%c_f32_8 = OpConstant %f32 8.0\n"                                                                                                                                              \
101         "%c_i32_0 = OpConstant %i32 0\n"                                                                                                                                                \
102         "%c_i32_1 = OpConstant %i32 1\n"                                                                                                                                                \
103         "%c_i32_2 = OpConstant %i32 2\n"                                                                                                                                                \
104         "%c_i32_3 = OpConstant %i32 3\n"                                                                                                                                                \
105         "%c_i32_4 = OpConstant %i32 4\n"                                                                                                                                                \
106         "%c_u32_0 = OpConstant %u32 0\n"                                                                                                                                                \
107         "%c_u32_1 = OpConstant %u32 1\n"                                                                                                                                                \
108         "%c_u32_2 = OpConstant %u32 2\n"                                                                                                                                                \
109         "%c_u32_3 = OpConstant %u32 3\n"                                                                                                                                                \
110         "%c_u32_32 = OpConstant %u32 32\n"                                                                                                                                              \
111         "%c_u32_4 = OpConstant %u32 4\n"                                                                                                                                                \
112         "%c_u32_31_bits = OpConstant %u32 0x7FFFFFFF\n"                                                                                                                 \
113         "%c_v4f32_1_1_1_1 = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_1\n"                                   \
114         "%c_v4f32_1_0_0_1 = OpConstantComposite %v4f32 %c_f32_1 %c_f32_0 %c_f32_0 %c_f32_1\n"                                   \
115         "%c_v4f32_0_5_0_5_0_5_0_5 = OpConstantComposite %v4f32 %c_f32_0_5 %c_f32_0_5 %c_f32_0_5 %c_f32_0_5\n"   \
116
117 #define SPIRV_ASSEMBLY_ARRAYS                                                                                                                                                           \
118         "%a1f32 = OpTypeArray %f32 %c_u32_1\n"                                                                                                                                  \
119         "%a2f32 = OpTypeArray %f32 %c_u32_2\n"                                                                                                                                  \
120         "%a3v4f32 = OpTypeArray %v4f32 %c_u32_3\n"                                                                                                                              \
121         "%a4f32 = OpTypeArray %f32 %c_u32_4\n"                                                                                                                                  \
122         "%a32v4f32 = OpTypeArray %v4f32 %c_u32_32\n"                                                                                                                    \
123         "%ip_a3v4f32 = OpTypePointer Input %a3v4f32\n"                                                                                                                  \
124         "%ip_a32v4f32 = OpTypePointer Input %a32v4f32\n"                                                                                                                \
125         "%op_a2f32 = OpTypePointer Output %a2f32\n"                                                                                                                             \
126         "%op_a3v4f32 = OpTypePointer Output %a3v4f32\n"                                                                                                                 \
127         "%op_a4f32 = OpTypePointer Output %a4f32\n"                                                                                                                             \
128
129 /*--------------------------------------------------------------------*//*!
130  * \brief Abstract class for an input/output storage buffer object
131  *//*--------------------------------------------------------------------*/
132 class BufferInterface
133 {
134 public:
135         virtual                         ~BufferInterface        (void)                          {}
136
137         virtual void            getBytes                        (std::vector<deUint8>& bytes) const = 0;
138         virtual void            getPackedBytes          (std::vector<deUint8>& bytes) const = 0;
139         virtual size_t          getByteSize                     (void) const = 0;
140 };
141
142 typedef de::SharedPtr<BufferInterface>  BufferSp;
143 typedef de::MovePtr<vk::Allocation>             AllocationMp;
144 typedef de::SharedPtr<vk::Allocation>   AllocationSp;
145
146 class Resource
147 {
148 public:
149         Resource(const BufferSp& buffer_, vk::VkDescriptorType descriptorType_ = vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
150                 : buffer(buffer_)
151                 , descriptorType(descriptorType_)
152         {
153         }
154
155         virtual const BufferSp&                 getBuffer                       () const                                                        { return buffer; }
156         virtual void                                    getBytes                        (std::vector<deUint8>& bytes) const     { buffer->getBytes(bytes); }
157         virtual size_t                                  getByteSize                     (void) const                                            { return buffer->getByteSize(); }
158
159         virtual void                                    setDescriptorType       (vk::VkDescriptorType type)             { descriptorType = type; }
160         virtual vk::VkDescriptorType    getDescriptorType       ()      const                                           { return descriptorType; }
161
162 private:
163         BufferSp                                buffer;
164         vk::VkDescriptorType    descriptorType;
165 };
166
167 typedef bool (*VerifyIOFunc) (const std::vector<Resource>&              inputs,
168                                                           const std::vector<AllocationSp>&      outputAllocations,
169                                                           const std::vector<Resource>&          expectedOutputs,
170                                                           tcu::TestLog&                                         log);
171
172 struct SpecConstants
173 {
174 public:
175                                                         SpecConstants (void)
176                                                         {}
177
178         bool                                    empty (void) const
179                                                         {
180                                                                 return valuesBuffer.empty();
181                                                         }
182
183         size_t                                  getValuesCount (void) const
184                                                         {
185                                                                 return sizesBuffer.size();
186                                                         }
187
188         size_t                                  getValueSize (const size_t valueIndex) const
189                                                         {
190                                                                 return sizesBuffer[valueIndex];
191                                                         }
192
193         const void*                             getValuesBuffer (void) const
194                                                         {
195                                                                 if (valuesBuffer.size() == 0)
196                                                                         return DE_NULL;
197                                                                 else
198                                                                         return static_cast<const void*>(&valuesBuffer[0]);
199                                                         }
200
201         template<typename T>
202         void                                    append (const T value)
203                                                         {
204                                                                 append(&value, sizeof(value));
205                                                         }
206
207         void                                    append (const void* buf, const size_t byteSize)
208                                                         {
209                                                                 DE_ASSERT(byteSize > 0);
210
211                                                                 valuesBuffer.resize(valuesBuffer.size() + byteSize);
212                                                                 deMemcpy(&valuesBuffer[valuesBuffer.size() - byteSize], buf, byteSize);
213
214                                                                 sizesBuffer.push_back(byteSize);
215                                                         }
216
217 private:
218         std::vector<deUint8>    valuesBuffer;
219         std::vector<size_t>             sizesBuffer;
220 };
221
222 enum Extension8BitStorageFeatureBits
223 {
224         EXT8BITSTORAGEFEATURES_STORAGE_BUFFER                   = (1u << 1),
225         EXT8BITSTORAGEFEATURES_UNIFORM_STORAGE_BUFFER   = (1u << 2),
226         EXT8BITSTORAGEFEATURES_PUSH_CONSTANT                    = (1u << 3),
227 };
228 typedef deUint32 Extension8BitStorageFeatures;
229
230 enum Extension16BitStorageFeatureBits
231 {
232         EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK    = (1u << 1),
233         EXT16BITSTORAGEFEATURES_UNIFORM                                 = (1u << 2),
234         EXT16BITSTORAGEFEATURES_PUSH_CONSTANT                   = (1u << 3),
235         EXT16BITSTORAGEFEATURES_INPUT_OUTPUT                    = (1u << 4),
236 };
237 typedef deUint32 Extension16BitStorageFeatures;
238
239 enum ExtensionVariablePointersFeaturesBits
240 {
241         EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS_STORAGEBUFFER     = (1u << 1),
242         EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS                           = (1u << 2),
243 };
244 typedef deUint32 ExtensionVariablePointersFeatures;
245
246 enum ExtensionFloat16Int8FeaturesBits
247 {
248         EXTFLOAT16INT8FEATURES_FLOAT16  = (1u << 1),
249         EXTFLOAT16INT8FEATURES_INT8             = (1u << 2),
250 };
251 typedef deUint32 ExtensionFloat16Int8Features;
252 typedef vk::VkPhysicalDeviceFloatControlsPropertiesKHR ExtensionFloatControlsFeatures;
253
254 enum ExtensionVulkanMemoryModelFeaturesBits
255 {
256         EXTVULKANMEMORYMODELFEATURES_ENABLE                                                     = (1u << 1),
257         EXTVULKANMEMORYMODELFEATURES_DEVICESCOPE                                        = (1u << 2),
258         EXTVULKANMEMORYMODELFEATURES_AVAILABILITYVISIBILITYCHAINS       = (1u << 3),
259 };
260 typedef deUint32 ExtensionVulkanMemoryModelFeatures;
261
262 struct VulkanFeatures
263 {
264         vk::VkPhysicalDeviceFeatures            coreFeatures;
265         ExtensionFloat16Int8Features            extFloat16Int8;
266         Extension8BitStorageFeatures            ext8BitStorage;
267         Extension16BitStorageFeatures           ext16BitStorage;
268         ExtensionVariablePointersFeatures       extVariablePointers;
269         ExtensionVulkanMemoryModelFeatures      extVulkanMemoryModel;
270         ExtensionFloatControlsFeatures          floatControlsProperties;
271
272
273         VulkanFeatures                          (void)
274                 : extFloat16Int8                (0)
275                 , ext8BitStorage                (0)
276                 , ext16BitStorage               (0)
277                 , extVariablePointers   (0)
278                 , extVulkanMemoryModel  (0)
279         {
280                 deMemset(&coreFeatures, 0, sizeof(coreFeatures));
281                 deMemset(&floatControlsProperties, 0, sizeof(ExtensionFloatControlsFeatures));
282                 floatControlsProperties.denormBehaviorIndependence      = vk::VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR;
283                 floatControlsProperties.roundingModeIndependence        = vk::VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR;
284         }
285 };
286
287 struct VariableLocation
288 {
289         deUint32 set;
290         deUint32 binding;
291
292         // Returns a string representation of the structure suitable for test names.
293         std::string toString() const ;
294
295         // Returns a string representation of the structure suitable for test descriptions.
296         std::string toDescription() const;
297 };
298
299 // Returns true if the given 8bit storage extension features in `toCheck` are all supported.
300 bool is8BitStorageFeaturesSupported (const Context&                                             context,
301                                                                           Extension8BitStorageFeatures          toCheck);
302
303 // Returns true if the given 16bit storage extension features in `toCheck` are all supported.
304 bool isCoreFeaturesSupported (const Context&                                            context,
305                                                           const vk::VkPhysicalDeviceFeatures&   toCheck,
306                                                           const char**                                                  missingFeature);
307
308 // Returns true if the given 16bit storage extension features in `toCheck` are all supported.
309 bool isCoreFeaturesSupported (const Context&                                            context,
310                                                           const vk::VkPhysicalDeviceFeatures&   toCheck,
311                                                           const char**                                                  missingFeature);
312
313 // Returns true if the given 16bit storage extension features in `toCheck` are all supported.
314 bool is16BitStorageFeaturesSupported (const Context&                            context,
315                                                                           Extension16BitStorageFeatures toCheck);
316
317 // Returns true if the given variable pointers extension features in `toCheck` are all supported.
318 bool isVariablePointersFeaturesSupported (const Context&                                        context,
319                                                                                   ExtensionVariablePointersFeatures     toCheck);
320
321 // Returns true if the given 16bit float/8bit int extension features in `toCheck` are all supported.
322 bool isFloat16Int8FeaturesSupported (const Context&                                     context,
323                                                                          ExtensionFloat16Int8Features   toCheck);
324
325 // Returns true if the given Vulkan Memory Model extension features in `toCheck` are all supported.
326 bool isVulkanMemoryModelFeaturesSupported (const Context&                                               context,
327                                                                                    ExtensionVulkanMemoryModelFeatures   toCheck);
328
329 // Returns true if the given float controls features in `toCheck` are all supported.
330 bool isFloatControlsFeaturesSupported (const Context&                                                   context,
331                                                                            const ExtensionFloatControlsFeatures&        toCheck);
332
333 deUint32 getMinRequiredVulkanVersion (const vk::SpirvVersion version);
334
335 std::string     getVulkanName (const deUint32 version);
336
337 // Performs a bitwise copy of source to the destination type Dest.
338 template <typename Dest, typename Src>
339 Dest bitwiseCast (Src source)
340 {
341   Dest dest;
342   DE_STATIC_ASSERT(sizeof(source) == sizeof(dest));
343   deMemcpy(&dest, &source, sizeof(dest));
344   return dest;
345 }
346
347 // Generate and return 64-bit integers.
348 //
349 // Expected count to be at least 16.
350 std::vector<deInt64> getInt64s (de::Random& rnd, const deUint32 count);
351
352 // Generate and return 32-bit integers.
353 //
354 // Expected count to be at least 16.
355 std::vector<deInt32> getInt32s (de::Random& rnd, const deUint32 count);
356
357 // Generate and return 16-bit integers.
358 //
359 // Expected count to be at least 8.
360 std::vector<deInt16> getInt16s (de::Random& rnd, const deUint32 count);
361
362 // Generate and return 8-bit integers.
363 //
364 // Expected count to be at least 8.
365 std::vector<deInt8> getInt8s (de::Random& rnd, const deUint32 count);
366
367 // Generate and return 64-bit floats
368 //
369 // The first 24 number pairs are manually picked, while the rest are randomly generated.
370 // Expected count to be at least 24 (numPicks).
371 std::vector<double> getFloat64s (de::Random& rnd, deUint32 count);
372
373 // Generate and return 32-bit floats
374 //
375 // The first 24 number pairs are manually picked, while the rest are randomly generated.
376 // Expected count to be at least 24 (numPicks).
377 std::vector<float> getFloat32s (de::Random& rnd, deUint32 count);
378
379 // Generate and return 16-bit floats and their corresponding 32-bit values.
380 //
381 // The first 14 number pairs are manually picked, while the rest are randomly generated.
382 // Expected count to be at least 14 (numPicks).
383 std::vector<deFloat16> getFloat16s (de::Random& rnd, deUint32 count);
384
385 // Generate an OpCapability Shader line.
386 std::string getOpCapabilityShader();
387
388 // Generate an unused Vertex entry point.
389 std::string getUnusedEntryPoint();
390
391 // Generate unused decorations for an input/output buffer.
392 std::string getUnusedDecorations(const VariableLocation& location);
393
394 // Generate unused types and constants, including a buffer type.
395 std::string getUnusedTypesAndConstants();
396
397 // Generate the declaration of an unused buffer variable.
398 std::string getUnusedBuffer();
399
400 // Generate the body of an unused function that uses the previous buffer.
401 std::string getUnusedFunctionBody();
402
403 } // SpirVAssembly
404 } // vkt
405
406 #endif // _VKTSPVASMUTILS_HPP