1 #ifndef _VKTSUBGROUPSTESTSUTILS_HPP 2 #define _VKTSUBGROUPSTESTSUTILS_HPP 3 /*------------------------------------------------------------------------ 4 * Vulkan Conformance Tests 5 * ------------------------ 6 * 7 * Copyright (c) 2017 The Khronos Group Inc. 8 * Copyright (c) 2017 Codeplay Software Ltd. 9 * 10 * Licensed under the Apache License, Version 2.0 (the "License"); 11 * you may not use this file except in compliance with the License. 12 * You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, software 17 * distributed under the License is distributed on an "AS IS" BASIS, 18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 * See the License for the specific language governing permissions and 20 * limitations under the License. 21 * 22 */ /*! 23 * \file 24 * \brief Subgroups tests utility classes 25 */ /*--------------------------------------------------------------------*/ 26 27 #include "vkBuilderUtil.hpp" 28 #include "vkDefs.hpp" 29 #include "vkDeviceUtil.hpp" 30 #include "vkMemUtil.hpp" 31 #include "vkPlatform.hpp" 32 #include "vkPrograms.hpp" 33 #include "vkQueryUtil.hpp" 34 #include "vkRef.hpp" 35 #include "vkRefUtil.hpp" 36 #include "vkStrUtil.hpp" 37 #include "vkTypeUtil.hpp" 38 #include "vktTestCase.hpp" 39 #include "vktTestCaseUtil.hpp" 40 #include "vkRayTracingUtil.hpp" 41 42 #include "tcuFormatUtil.hpp" 43 #include "tcuTestLog.hpp" 44 #include "tcuVectorUtil.hpp" 45 46 #include "gluShaderUtil.hpp" 47 48 #include "deSharedPtr.hpp" 49 #include "deUniquePtr.hpp" 50 51 #include <string> 52 #include <vector> 53 54 namespace vkt 55 { 56 namespace subgroups 57 { 58 typedef bool (*CheckResult)(const void *internalData, std::vector<const void *> datas, uint32_t width, 59 uint32_t subgroupSize); 60 typedef bool (*CheckResultFragment)(const void *internalData, std::vector<const void *> datas, uint32_t width, 61 uint32_t height, uint32_t subgroupSize); 62 typedef bool (*CheckResultCompute)(const void *internalData, std::vector<const void *> datas, 63 const uint32_t numWorkgroups[3], const uint32_t localSize[3], uint32_t subgroupSize); 64 65 // A struct to represent input data to a shader 66 struct SSBOData 67 { 68 enum InputDataInitializeType 69 { 70 InitializeNone = 0, 71 InitializeNonZero, 72 InitializeZero, 73 }; 74 enum InputDataLayoutType 75 { 76 LayoutStd140 = 0, 77 LayoutStd430, 78 LayoutPacked 79 }; 80 81 enum BindingType 82 { 83 BindingSSBO, 84 BindingImage, 85 BindingUBO, 86 }; 87 SSBODatavkt::subgroups::SSBOData88 SSBOData() 89 : initializeType(InitializeNone) 90 , layout(LayoutStd140) 91 , format(vk::VK_FORMAT_UNDEFINED) 92 , numElements(0) 93 , bindingType(BindingSSBO) 94 , binding(0u) 95 , stages((vk::VkShaderStageFlags)0u) 96 { 97 } 98 SSBODatavkt::subgroups::SSBOData99 SSBOData(InputDataInitializeType initializeType_, InputDataLayoutType layout_, vk::VkFormat format_, 100 vk::VkDeviceSize numElements_, BindingType bindingType_ = BindingSSBO, uint32_t binding_ = 0u, 101 vk::VkShaderStageFlags stages_ = static_cast<vk::VkShaderStageFlags>(0u)) 102 : initializeType(initializeType_) 103 , layout(layout_) 104 , format(format_) 105 , numElements(numElements_) 106 , bindingType(bindingType_) 107 , binding(binding_) 108 , stages(stages_) 109 { 110 if (bindingType == BindingUBO) 111 DE_ASSERT(layout == LayoutStd140); 112 } 113 isImagevkt::subgroups::SSBOData114 bool isImage() const 115 { 116 return (bindingType == BindingImage); 117 } 118 isUBOvkt::subgroups::SSBOData119 bool isUBO() const 120 { 121 return (bindingType == BindingUBO); 122 } 123 124 InputDataInitializeType initializeType; 125 InputDataLayoutType layout; 126 vk::VkFormat format; 127 vk::VkDeviceSize numElements; 128 BindingType bindingType; 129 uint32_t binding; 130 vk::VkShaderStageFlags stages; 131 }; 132 133 uint32_t getStagesCount(vk::VkShaderStageFlags shaderStages); 134 135 std::string getSharedMemoryBallotHelper(); 136 137 std::string getSharedMemoryBallotHelperARB(); 138 139 uint32_t getSubgroupSize(Context &context); 140 141 uint32_t maxSupportedSubgroupSize(); 142 143 std::string getShaderStageName(vk::VkShaderStageFlags stage); 144 145 std::string getSubgroupFeatureName(vk::VkSubgroupFeatureFlagBits bit); 146 147 void addNoSubgroupShader(vk::SourceCollections &programCollection); 148 149 void initStdFrameBufferPrograms(vk::SourceCollections &programCollection, const vk::ShaderBuildOptions &buildOptions, 150 vk::VkShaderStageFlags shaderStage, vk::VkFormat format, bool gsPointSize, 151 const std::string &extHeader, const std::string &testSrc, const std::string &helperStr, 152 const std::vector<std::string> &declarations = std::vector<std::string>()); 153 154 void initStdPrograms(vk::SourceCollections &programCollection, const vk::ShaderBuildOptions &buildOptions, 155 vk::VkShaderStageFlags shaderStage, vk::VkFormat format, bool gsPointSize, 156 const std::string &extHeader, const std::string &testSrc, const std::string &helperStr, 157 const std::vector<std::string> &declarations = std::vector<std::string>(), 158 const bool avoidHelperInvocations = false, const std::string &tempRes = " uint tempRes;\n"); 159 160 bool isSubgroupSupported(Context &context); 161 162 bool areSubgroupOperationsSupportedForStage(Context &context, vk::VkShaderStageFlags stage); 163 164 bool isSubgroupFeatureSupportedForDevice(Context &context, vk::VkSubgroupFeatureFlagBits bit); 165 166 bool areQuadOperationsSupportedForStages(Context &context, const vk::VkShaderStageFlags stages); 167 168 bool isFragmentSSBOSupportedForDevice(Context &context); 169 170 bool isVertexSSBOSupportedForDevice(Context &context); 171 172 bool isFormatSupportedForDevice(Context &context, vk::VkFormat format); 173 174 bool isInt64SupportedForDevice(Context &context); 175 176 bool isTessellationAndGeometryPointSizeSupported(Context &context); 177 178 bool is16BitUBOStorageSupported(Context &context); 179 180 bool is8BitUBOStorageSupported(Context &context); 181 182 bool isSubgroupBroadcastDynamicIdSupported(Context &context); 183 184 bool isSubgroupRotateSpecVersionValid(Context &context); 185 186 std::string getFormatNameForGLSL(vk::VkFormat format); 187 188 std::string getAdditionalExtensionForFormat(vk::VkFormat format); 189 190 const std::vector<vk::VkFormat> getAllFormats(); 191 192 bool isFormatSigned(vk::VkFormat format); 193 bool isFormatUnsigned(vk::VkFormat format); 194 bool isFormatFloat(vk::VkFormat format); 195 bool isFormatBool(vk::VkFormat format); 196 bool isFormat8bitTy(vk::VkFormat format); 197 bool isFormat16BitTy(vk::VkFormat format); 198 199 void addGeometryShadersFromTemplate(const std::string &glslTemplate, const vk::ShaderBuildOptions &options, 200 vk::GlslSourceCollection &collection); 201 void addGeometryShadersFromTemplate(const std::string &spirvTemplate, const vk::SpirVAsmBuildOptions &options, 202 vk::SpirVAsmCollection &collection); 203 204 void setVertexShaderFrameBuffer(vk::SourceCollections &programCollection); 205 206 void setFragmentShaderFrameBuffer(vk::SourceCollections &programCollection); 207 208 void setFragmentShaderFrameBuffer(vk::SourceCollections &programCollection); 209 210 void setTesCtrlShaderFrameBuffer(vk::SourceCollections &programCollection); 211 212 void setTesEvalShaderFrameBuffer(vk::SourceCollections &programCollection); 213 214 bool check(std::vector<const void *> datas, uint32_t width, uint32_t ref); 215 216 bool checkComputeOrMesh(std::vector<const void *> datas, const uint32_t numWorkgroups[3], const uint32_t localSize[3], 217 uint32_t ref); 218 219 tcu::TestStatus makeTessellationEvaluationFrameBufferTest( 220 Context &context, vk::VkFormat format, const SSBOData *extraData, uint32_t extraDataCount, const void *internalData, 221 CheckResult checkResult, const vk::VkShaderStageFlags shaderStage = vk::VK_SHADER_STAGE_ALL_GRAPHICS); 222 223 tcu::TestStatus makeGeometryFrameBufferTest(Context &context, vk::VkFormat format, const SSBOData *extraData, 224 uint32_t extraDataCount, const void *internalData, CheckResult checkResult); 225 226 // Allows using verification functions with or without the optional last boolean argument. 227 // If using a function that does not need the last argument, it will not be passed down to it. 228 class VerificationFunctor 229 { 230 public: 231 using NoLastArgVariant = bool (*)(const void *, std::vector<const void *>, uint32_t, uint32_t); 232 using AllArgsVariant = bool (*)(const void *, std::vector<const void *>, uint32_t, uint32_t, bool); 233 VerificationFunctor(NoLastArgVariant func)234 VerificationFunctor(NoLastArgVariant func) : m_noLastArgFunc{func}, m_allArgsFunc{nullptr} 235 { 236 } 237 VerificationFunctor(AllArgsVariant func)238 VerificationFunctor(AllArgsVariant func) : m_noLastArgFunc{nullptr}, m_allArgsFunc{func} 239 { 240 } 241 operator ()(const void * extraData,std::vector<const void * > datas,uint32_t width,uint32_t subgroupSize,bool multipleCallsPossible) const242 bool operator()(const void *extraData, std::vector<const void *> datas, uint32_t width, uint32_t subgroupSize, 243 bool multipleCallsPossible) const 244 { 245 if (m_allArgsFunc) 246 return m_allArgsFunc(extraData, datas, width, subgroupSize, multipleCallsPossible); 247 return m_noLastArgFunc(extraData, datas, width, subgroupSize); 248 } 249 250 private: 251 NoLastArgVariant m_noLastArgFunc; 252 AllArgsVariant m_allArgsFunc; 253 }; 254 255 vk::VkShaderStageFlags getPossibleGraphicsSubgroupStages(Context &context, const vk::VkShaderStageFlags testedStages); 256 257 tcu::TestStatus allStages(Context &context, vk::VkFormat format, const SSBOData *extraData, uint32_t extraDataCount, 258 const void *internalData, const VerificationFunctor &checkResult, 259 const vk::VkShaderStageFlags shaderStage); 260 261 tcu::TestStatus makeVertexFrameBufferTest(Context &context, vk::VkFormat format, const SSBOData *extraData, 262 uint32_t extraDataCount, const void *internalData, CheckResult checkResult); 263 264 tcu::TestStatus makeFragmentFrameBufferTest(Context &context, vk::VkFormat format, const SSBOData *extraData, 265 uint32_t extraDataCount, const void *internalData, 266 CheckResultFragment checkResult); 267 268 tcu::TestStatus makeComputeTest(Context &context, vk::VkFormat format, const SSBOData *inputs, uint32_t inputsCount, 269 const void *internalData, CheckResultCompute checkResult, 270 uint32_t requiredSubgroupSize = 0u, const uint32_t pipelineShaderStageCreateFlags = 0u); 271 272 tcu::TestStatus makeMeshTest(Context &context, vk::VkFormat format, const SSBOData *inputs, uint32_t inputsCount, 273 const void *internalData, CheckResultCompute checkResult, 274 uint32_t requiredSubgroupSize = 0u, const uint32_t pipelineShaderStageCreateFlags = 0u); 275 276 /* Functions needed for VK_EXT_subgroup_size_control tests */ 277 tcu::TestStatus makeTessellationEvaluationFrameBufferTestRequiredSubgroupSize( 278 Context &context, vk::VkFormat format, const SSBOData *extraData, uint32_t extraDataCount, const void *internalData, 279 CheckResult checkResult, const vk::VkShaderStageFlags shaderStage = vk::VK_SHADER_STAGE_ALL_GRAPHICS, 280 const uint32_t tessShaderStageCreateFlags = 0u, const uint32_t requiredSubgroupSize = 0u); 281 282 tcu::TestStatus makeGeometryFrameBufferTestRequiredSubgroupSize(Context &context, vk::VkFormat format, 283 const SSBOData *extraData, uint32_t extraDataCount, 284 const void *internalData, CheckResult checkResult, 285 const uint32_t geometryShaderStageCreateFlags = 0u, 286 const uint32_t requiredSubgroupSize = 0u); 287 288 tcu::TestStatus allStagesRequiredSubgroupSize( 289 Context &context, vk::VkFormat format, const SSBOData *extraDatas, uint32_t extraDatasCount, 290 const void *internalData, const VerificationFunctor &checkResult, const vk::VkShaderStageFlags shaderStageTested, 291 const uint32_t vertexShaderStageCreateFlags, const uint32_t tessellationControlShaderStageCreateFlags, 292 const uint32_t tessellationEvalShaderStageCreateFlags, const uint32_t geometryShaderStageCreateFlags, 293 const uint32_t fragmentShaderStageCreateFlags, const uint32_t requiredSubgroupSize[5]); 294 295 tcu::TestStatus makeVertexFrameBufferTestRequiredSubgroupSize(Context &context, vk::VkFormat format, 296 const SSBOData *extraData, uint32_t extraDataCount, 297 const void *internalData, CheckResult checkResult, 298 const uint32_t vertexShaderStageCreateFlags = 0u, 299 const uint32_t requiredSubgroupSize = 0u); 300 301 tcu::TestStatus makeFragmentFrameBufferTestRequiredSubgroupSize(Context &context, vk::VkFormat format, 302 const SSBOData *extraData, uint32_t extraDataCount, 303 const void *internalData, 304 CheckResultFragment checkResult, 305 const uint32_t fragmentShaderStageCreateFlags = 0u, 306 const uint32_t requiredSubgroupSize = 0u); 307 308 tcu::TestStatus makeComputeTestRequiredSubgroupSize(Context &context, vk::VkFormat format, const SSBOData *inputs, 309 uint32_t inputsCount, const void *internalData, 310 CheckResultCompute checkResult, 311 const uint32_t pipelineShaderStageCreateFlags, 312 const uint32_t numWorkgroups[3], const bool isRequiredSubgroupSize, 313 const uint32_t subgroupSize, const uint32_t localSizesToTest[][3], 314 const uint32_t localSizesToTestCount); 315 316 tcu::TestStatus makeMeshTestRequiredSubgroupSize(Context &context, vk::VkFormat format, const SSBOData *inputs, 317 uint32_t inputsCount, const void *internalData, 318 CheckResultCompute checkResult, 319 const uint32_t pipelineShaderStageCreateFlags, 320 const uint32_t numWorkgroups[3], const bool isRequiredSubgroupSize, 321 const uint32_t subgroupSize, const uint32_t localSizesToTest[][3], 322 const uint32_t localSizesToTestCount); 323 324 void supportedCheckShader(Context &context, const vk::VkShaderStageFlags shaderStage); 325 326 const std::vector<vk::VkFormat> getAllRayTracingFormats(); 327 328 void addRayTracingNoSubgroupShader(vk::SourceCollections &programCollection); 329 330 vk::VkShaderStageFlags getPossibleRayTracingSubgroupStages(Context &context, const vk::VkShaderStageFlags testedStages); 331 332 tcu::TestStatus allRayTracingStages(Context &context, vk::VkFormat format, const SSBOData *extraData, 333 uint32_t extraDataCount, const void *internalData, 334 const VerificationFunctor &checkResult, const vk::VkShaderStageFlags shaderStage); 335 336 tcu::TestStatus allRayTracingStagesRequiredSubgroupSize( 337 Context &context, vk::VkFormat format, const SSBOData *extraDatas, uint32_t extraDatasCount, 338 const void *internalData, const VerificationFunctor &checkResult, const vk::VkShaderStageFlags shaderStageTested, 339 const uint32_t shaderStageCreateFlags[6], const uint32_t requiredSubgroupSize[6]); 340 } // namespace subgroups 341 } // namespace vkt 342 343 #endif // _VKTSUBGROUPSTESTSUTILS_HPP 344