Merge vk-gl-cts/vulkan-cts-1.0.2 into vk-gl-cts/vulkan-cts-1.1.0
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / spirv_assembly / vktSpvAsmUtils.cpp
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 Google Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Utilities for Vulkan SPIR-V assembly tests
22  *//*--------------------------------------------------------------------*/
23
24 #include "vktSpvAsmUtils.hpp"
25
26 #include "deMemory.h"
27 #include "deSTLUtil.hpp"
28 #include "vkQueryUtil.hpp"
29 #include "vkRefUtil.hpp"
30
31 namespace vkt
32 {
33 namespace SpirVAssembly
34 {
35
36 using namespace vk;
37
38 namespace
39 {
40
41 VkPhysicalDeviceFeatures filterDefaultDeviceFeatures (const VkPhysicalDeviceFeatures& deviceFeatures)
42 {
43         VkPhysicalDeviceFeatures enabledDeviceFeatures = deviceFeatures;
44
45         // Disable robustness by default, as it has an impact on performance on some HW.
46         enabledDeviceFeatures.robustBufferAccess = false;
47
48         return enabledDeviceFeatures;
49 }
50
51 VkPhysicalDevice16BitStorageFeatures    querySupported16BitStorageFeatures (const deUint32 apiVersion, const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions)
52 {
53         VkPhysicalDevice16BitStorageFeatures    extensionFeatures       =
54         {
55                 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR,   // sType
56                 DE_NULL,                                                                                                                // pNext
57                 false,                                                                                                                  // storageUniformBufferBlock16
58                 false,                                                                                                                  // storageUniform16
59                 false,                                                                                                                  // storagePushConstant16
60                 false,                                                                                                                  // storageInputOutput16
61         };
62         VkPhysicalDeviceFeatures2                       features;
63
64         deMemset(&features, 0, sizeof(features));
65         features.sType  = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
66         features.pNext  = &extensionFeatures;
67
68         // Call the getter only if supported. Otherwise above "zero" defaults are used
69         if(isInstanceExtensionSupported(apiVersion, instanceExtensions, "VK_KHR_get_physical_device_properties2"))
70         {
71                 vki.getPhysicalDeviceFeatures2(device, &features);
72         }
73
74         return extensionFeatures;
75 }
76
77 VkPhysicalDeviceVariablePointerFeatures querySupportedVariablePointersFeatures (const deUint32 apiVersion, const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions)
78 {
79         VkPhysicalDeviceVariablePointerFeatures extensionFeatures       =
80         {
81                 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR,        // sType
82                 DE_NULL,                                                                                                                        // pNext
83                 false,                                                                                                                          // variablePointersStorageBuffer
84                 false,                                                                                                                          // variablePointers
85         };
86
87         VkPhysicalDeviceFeatures2       features;
88         deMemset(&features, 0, sizeof(features));
89         features.sType  = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
90         features.pNext  = &extensionFeatures;
91
92         // Call the getter only if supported. Otherwise above "zero" defaults are used
93         if(isInstanceExtensionSupported(apiVersion, instanceExtensions, "VK_KHR_get_physical_device_properties2"))
94         {
95                 vki.getPhysicalDeviceFeatures2(device, &features);
96         }
97
98         return extensionFeatures;
99 }
100
101 } // anonymous
102
103 bool is16BitStorageFeaturesSupported (const deUint32 apiVersion, const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions, Extension16BitStorageFeatures toCheck)
104 {
105         VkPhysicalDevice16BitStorageFeatures extensionFeatures  = querySupported16BitStorageFeatures(apiVersion, vki, device, instanceExtensions);
106
107         if ((toCheck & EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK) != 0 && extensionFeatures.storageBuffer16BitAccess == VK_FALSE)
108                 return false;
109
110         if ((toCheck & EXT16BITSTORAGEFEATURES_UNIFORM) != 0 && extensionFeatures.uniformAndStorageBuffer16BitAccess == VK_FALSE)
111                 return false;
112
113         if ((toCheck & EXT16BITSTORAGEFEATURES_PUSH_CONSTANT) != 0 && extensionFeatures.storagePushConstant16 == VK_FALSE)
114                 return false;
115
116         if ((toCheck & EXT16BITSTORAGEFEATURES_INPUT_OUTPUT) != 0 && extensionFeatures.storageInputOutput16 == VK_FALSE)
117                 return false;
118
119         return true;
120 }
121
122 bool isVariablePointersFeaturesSupported (const deUint32 apiVersion, const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions, ExtensionVariablePointersFeatures toCheck)
123 {
124         VkPhysicalDeviceVariablePointerFeatures extensionFeatures = querySupportedVariablePointersFeatures(apiVersion, vki, device, instanceExtensions);
125
126         if ((toCheck & EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS_STORAGEBUFFER) != 0 && extensionFeatures.variablePointersStorageBuffer == VK_FALSE)
127                 return false;
128
129         if ((toCheck & EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS) != 0 && extensionFeatures.variablePointers == VK_FALSE)
130                 return false;
131
132         return true;
133 }
134
135 Move<VkDevice> createDeviceWithExtensions (Context&                                                     context,
136                                                                                    const deUint32                                       queueFamilyIndex,
137                                                                                    const std::vector<std::string>&      supportedExtensions,
138                                                                                    const std::vector<std::string>&      requiredExtensions)
139 {
140         const InstanceInterface&                                        vki                                                     = context.getInstanceInterface();
141         const VkPhysicalDevice                                          physicalDevice                          = context.getPhysicalDevice();
142         std::vector<const char*>                                        extensions;
143         void*                                                                           pExtension                                      = DE_NULL;
144         const VkPhysicalDeviceFeatures                          deviceFeatures                          = getPhysicalDeviceFeatures(vki, physicalDevice);
145         VkPhysicalDevice16BitStorageFeatures            ext16BitStorageFeatures;
146         VkPhysicalDeviceVariablePointerFeatures         extVariablePointerFeatures;
147
148         for (deUint32 extNdx = 0; extNdx < requiredExtensions.size(); ++extNdx)
149         {
150                 const std::string&      ext = requiredExtensions[extNdx];
151
152                 // Check that all required extensions are supported first.
153                 if (!isDeviceExtensionSupported(context.getUsedApiVersion(), supportedExtensions, ext))
154                 {
155                         TCU_THROW(NotSupportedError, (std::string("Device extension not supported: ") + ext).c_str());
156                 }
157
158                 // Currently don't support enabling multiple extensions at the same time.
159                 if (ext == "VK_KHR_16bit_storage")
160                 {
161                         // For the 16bit storage extension, we have four features to test. Requesting all features supported.
162                         // Note that we don't throw NotImplemented errors here if a specific feature is not supported;
163                         // that should be done when actually trying to use that specific feature.
164                         ext16BitStorageFeatures = querySupported16BitStorageFeatures(context.getUsedApiVersion(), vki, physicalDevice, context.getInstanceExtensions());
165                         pExtension = &ext16BitStorageFeatures;
166                 }
167                 else if (ext == "VK_KHR_variable_pointers")
168                 {
169                         // For the VariablePointers extension, we have two features to test. Requesting all features supported.
170                         extVariablePointerFeatures      = querySupportedVariablePointersFeatures(context.getUsedApiVersion(), vki, physicalDevice, context.getInstanceExtensions());
171                         pExtension = &extVariablePointerFeatures;
172                 }
173
174                 if (!isCoreDeviceExtension(context.getUsedApiVersion(), ext))
175                         extensions.push_back(ext.c_str());
176         }
177
178         const float                                             queuePriorities[]       = { 1.0f };
179         const VkDeviceQueueCreateInfo   queueInfos[]            =
180         {
181                 {
182                         VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
183                         DE_NULL,
184                         (VkDeviceQueueCreateFlags)0,
185                         queueFamilyIndex,
186                         DE_LENGTH_OF_ARRAY(queuePriorities),
187                         &queuePriorities[0]
188                 }
189         };
190         const VkPhysicalDeviceFeatures  features                        = filterDefaultDeviceFeatures(deviceFeatures);
191         const VkDeviceCreateInfo                deviceParams            =
192         {
193                 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
194                 pExtension,
195                 (VkDeviceCreateFlags)0,
196                 DE_LENGTH_OF_ARRAY(queueInfos),
197                 &queueInfos[0],
198                 0u,
199                 DE_NULL,
200                 (deUint32)extensions.size(),
201                 extensions.empty() ? DE_NULL : &extensions[0],
202                 &features
203         };
204
205         return vk::createDevice(vki, physicalDevice, &deviceParams);
206 }
207
208 Allocator* createAllocator (const InstanceInterface& instanceInterface, const VkPhysicalDevice physicalDevice, const DeviceInterface& deviceInterface, const VkDevice device)
209 {
210         const VkPhysicalDeviceMemoryProperties memoryProperties = getPhysicalDeviceMemoryProperties(instanceInterface, physicalDevice);
211
212         // \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
213         return new SimpleAllocator(deviceInterface, device, memoryProperties);
214 }
215
216 deUint32 getMinRequiredVulkanVersion (const SpirvVersion version)
217 {
218         switch(version)
219         {
220         case SPIRV_VERSION_1_0:
221                 return VK_API_VERSION_1_0;
222         case SPIRV_VERSION_1_1:
223         case SPIRV_VERSION_1_2:
224         case SPIRV_VERSION_1_3:
225                 return VK_API_VERSION_1_1;
226         default:
227                 DE_ASSERT(0);
228         }
229         return 0u;
230 }
231
232 std::string     getVulkanName (const deUint32 version)
233 {
234         return std::string(version == VK_API_VERSION_1_1 ? "1.1" : "1.0");
235 }
236
237 } // SpirVAssembly
238 } // vkt