Add tests for SPV_KHR_variable_pointers extension
[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 VkPhysicalDevice16BitStorageFeaturesKHR querySupported16BitStorageFeatures (const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions)
52 {
53         VkPhysicalDevice16BitStorageFeaturesKHR 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         VkPhysicalDeviceFeatures2KHR                    features;
63
64         deMemset(&features, 0, sizeof(features));
65         features.sType  = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
66         features.pNext  = &extensionFeatures;
67
68         // Call the getter only if supported. Otherwise above "zero" defaults are used
69         if (de::contains(instanceExtensions.begin(), instanceExtensions.end(), "VK_KHR_get_physical_device_properties2"))
70         {
71                 vki.getPhysicalDeviceFeatures2KHR(device, &features);
72         }
73
74         return extensionFeatures;
75 }
76
77 VkPhysicalDeviceVariablePointerFeaturesKHR querySupportedVariablePointersFeatures (const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions)
78 {
79         VkPhysicalDeviceVariablePointerFeaturesKHR 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         VkPhysicalDeviceFeatures2KHR    features;
88         deMemset(&features, 0, sizeof(features));
89         features.sType  = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
90         features.pNext  = &extensionFeatures;
91
92         // Call the getter only if supported. Otherwise above "zero" defaults are used
93         if (de::contains(instanceExtensions.begin(), instanceExtensions.end(), "VK_KHR_get_physical_device_properties2"))
94         {
95                 vki.getPhysicalDeviceFeatures2KHR(device, &features);
96         }
97
98         return extensionFeatures;
99 }
100
101 } // anonymous
102
103 bool is16BitStorageFeaturesSupported (const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions, Extension16BitStorageFeatures toCheck)
104 {
105         VkPhysicalDevice16BitStorageFeaturesKHR extensionFeatures       = querySupported16BitStorageFeatures(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 InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions, ExtensionVariablePointersFeatures toCheck)
123 {
124         VkPhysicalDeviceVariablePointerFeaturesKHR extensionFeatures = querySupportedVariablePointersFeatures(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                                      (requiredExtensions.size());
143         void*                                                                           pExtension                                      = DE_NULL;
144         const VkPhysicalDeviceFeatures                          deviceFeatures                          = getPhysicalDeviceFeatures(vki, physicalDevice);
145         VkPhysicalDevice16BitStorageFeaturesKHR         ext16BitStorageFeatures;
146         VkPhysicalDeviceVariablePointerFeaturesKHR      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 (!de::contains(supportedExtensions.begin(), supportedExtensions.end(), 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(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(vki, physicalDevice, context.getInstanceExtensions());
171                         pExtension = &extVariablePointerFeatures;
172                 }
173
174                 extensions[extNdx] = ext.c_str();
175         }
176
177         const float                                             queuePriorities[]       = { 1.0f };
178         const VkDeviceQueueCreateInfo   queueInfos[]            =
179         {
180                 {
181                         VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
182                         DE_NULL,
183                         (VkDeviceQueueCreateFlags)0,
184                         queueFamilyIndex,
185                         DE_LENGTH_OF_ARRAY(queuePriorities),
186                         &queuePriorities[0]
187                 }
188         };
189         const VkPhysicalDeviceFeatures  features                        = filterDefaultDeviceFeatures(deviceFeatures);
190         const VkDeviceCreateInfo                deviceParams            =
191         {
192                 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
193                 pExtension,
194                 (VkDeviceCreateFlags)0,
195                 DE_LENGTH_OF_ARRAY(queueInfos),
196                 &queueInfos[0],
197                 0u,
198                 DE_NULL,
199                 (deUint32)extensions.size(),
200                 extensions.empty() ? DE_NULL : &extensions[0],
201                 &features
202         };
203
204         return vk::createDevice(vki, physicalDevice, &deviceParams);
205 }
206
207 Allocator* createAllocator (const InstanceInterface& instanceInterface, const VkPhysicalDevice physicalDevice, const DeviceInterface& deviceInterface, const VkDevice device)
208 {
209         const VkPhysicalDeviceMemoryProperties memoryProperties = getPhysicalDeviceMemoryProperties(instanceInterface, physicalDevice);
210
211         // \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
212         return new SimpleAllocator(deviceInterface, device, memoryProperties);
213 }
214
215 } // SpirVAssembly
216 } // vkt